Group by results in ling - c#

I have linq statement that returns value. The LINQ statement below will returns the systemUser Id and totalHours of a systemUser as shown below. However, what I really what is to get the Id and the total hours per system user. How to add group then in linq?
var th1 = (from ss in db.SystemUsers
join t in db.Timesheets on ss.Id equals t.SystemUser
where (t.Project == projectId && t.StartTime >= year_start && t.StartTime < year_end)
select new
{
ss.Id,
t.TotalHours
});
Id | TotalHours
1 | 10
1 | 20
2 | 10
2 | 5
and so on...
EXPECTED OUTPUT
Id | TotalHours
1 | 30
2 | 15
and so on...

You have to use GroupBy
var th1 =
from ss in db.SystemUsers
join t in db.Timesheets on ss.Id equals t.SystemUser
where (t.Project == projectId && t.StartTime >= year_start && t.StartTime < year_end)
group t by new { ss.Id } into g
select new
{
g.Key.Id,
TotalHours = g.Sum(x => x.TotalHours)
};

Related

How do I merge two count queries from one table?

The first query :
Id | UserId | projectId |date | Status
1 | 1 | 1 | 2020 | PENDDING
2 | 1 | 2 | 2020 | DONE
3 | 2 | 1 | 2020 | PENDDING
And what I tried two queries :
the first is about to get all userwork with X project for example id = 1
var FirstQery = context.table1.where (C => C.ProjectId == 1).count();
The second query is to fetch the number of user with project x have "done"status
var SecondQery = context.table1.where (C => C.ProjectId == 1 && C.Status == "DONE").count();
I want return object have only two values : countNumberUserWithXProject
and countNumberUserByXProjectHaveXStatus
It is known approach with fake grouping.
var query =
from t in context.table1
where t.ProjectId == 1
group t by 1 into g
select new
{
Count = g.Count(),
DoneCount = g.Sum(x => x.Status == "DONE" ? 1 : 0)
}
var result = query.FirstOrDefault();
How about returning an anonymous object (or if you like it more a typized object like a int[]).
return new {count1 = FirstQery , count2 = SecondQery };
(Return, or assign like var result = new {count1....} etc
You can also replace the FirstQuery and SecondQuery directly with the Linq query.

Join data from multiple tables and group by Date and Id from another table using linq

I have these queries which retrieve results from multiple tables and want the expected result given below, Here is my code:
var q1 = (from sh in SessionHistories
where (System.DateTime.Now >= sh.FromDate && System.DateTime.Now <= sh.ToDate) && sh.IsDeleted == false
select sh
).ToList();
var FromDate = (from q in q1 select q.FromDate.Value).FirstOrDefault();
var ToDate = (from q in q1 select q.ToDate.Value).FirstOrDefault();
var allDates = (from idx in Enumerable.Range(0, (System.DateTime.Now - FromDate).Days)
select FromDate.AddDays(idx)).OrderBy(x => x.Date).ToList();
var q2 = (from ci in View_checkinout
where ci.EmployeeId == 2183
group ci by new { ci.CheckTime.Date } into g
select new
{
AttendanceDate = g.Key.Date,
EmployeeId = g.Select(x => x.EmployeeId).FirstOrDefault(),
CheckInTime = g.Select(x => new { x.CheckTime, x.CheckType }).Where(x => x.CheckType == "I").FirstOrDefault(),
CheckOutTime = g.Select(x => new { x.CheckTime, x.CheckType }).Where(x => x.CheckType == "O").OrderByDescending(x => x.CheckTime).FirstOrDefault()
})
.ToList();
var q3 = (from ad in allDates
join q in q2 on ad.Date equals q.AttendanceDate into outer
from o1 in outer.DefaultIfEmpty()
select new
{
o1,
ad
}).ToList();
and here is the expected result:
| EmployeeName | Designation | Late Arrivals| Short Leave| Half Leave| Full Leave| Cur. Month Total| Prev. Total|
|---------------|--------------|--------------|------------|------------|------------|------------|
| Name | Teacher| 0 | 0 |
| Name | Admin | 20 | 0 |
| Name | Peon | 0 | 30 |

Converting SQL Join Query to Linq query

i want to join different column where the output would be this using linq
| Name | Address | Cellphone | Email |
| John | NY | n/a | johndoe#y.c |
| John | NY | 123456781 | n/a |
And i want my output to be one liner combined
| Name | Address | Cellphone | Email |
| John | NY | 123456781 | johndoe#y.c |
I Tried it on SQL server and this is the Query that answers the needed output
select a.ID, a.Name , a.Address ,(
SELECT wc1.[Values]
FROM Contact as wc1 where wc1.infoID = a.ID and wc1.ContactTypeID = 56) as Email
,(
SELECT wc1.[Values]
FROM Contact as wc1 where wc1.infoID = a.ID and wc1.ContactTypeID = 59) as Cellphone
from Info as a where a.ID = 100
Also tried it on Linq but it produces different row with same ID
var an = (from a in db.Info
join b in db.Contact on a.ID equals b.InfoID
where b.ContactTypeID == 56
|| b.ContactTypeID == 59
select new
{
a.ID,
a.LastName,
a.FirstName,
a.MiddleName,
b.ContactTypeID,
b.Values
}).ToList();
List<InfoList> wlist = new List<InfoList>();
foreach (var row in an)
{
InfoList ci = new InfoList
{
ID = row.ID,
Name = row.FirstName + " " + row.MiddleName + " " + row.LastName,
ContactType = GetLookupDisplayValById(row.ContactTypeID),
ContactValue = row.Values
};
wlist.Add(ci);
}
return Json(wlist.ToList(), JsonRequestBehavior.AllowGet);
Can someone help me translate this to a Linq Statement
Your SQL does not use JOIN, so why are you trying to introduce it in LINQ?
var an = (from a in db.Info
select new
{
a.ID,
a.LastName,
a.FirstName,
a.MiddleName,
Email = db.Contact.FirstOrDefault(b => b.InfoID == a.ID && b.ContactTypeIF == 56).Values,
Cellphone = db.Contact.FirstOrDefault(b => b.InfoID == a.ID && b.ContactTypeIF == 59).Values,
}).FirstOrDefault(x => x.ID == 100);
You can use the Pivot table the mentioned link shows how to use it: http://www.codeproject.com/Tips/500811/Simple-Way-To-Use-Pivot-In-SQL-Query

Entity framework where, order and group

I'm using the following LINQ to select data from a table:
(from m in entity.Results
where m.Group == 0 ||
m.Group == 1
orderby m.Points descending
select m);
This gives me a result of all Users who are in Group 1 or 2. With that i can display the points they have. But this shows me the points they have in Group 1 and Group 2 separately.
How can i group them and display the total points they have? So instead of this (What i have now):
user1 - group1 - 10
user1 - group2 - 7
user2 - group1 - 7
user2 - group2 - 5
I want this:
user1 - total: 17
user2 - total: 12
How do i have to adjust my query to get a result set like that?
You need to group the users, then use Sum to calculate the TotalPoints:
from m in entity.Results
where m.Group == 0 || m.Group == 1
group m by m.User into g
let TotalPoints = g.Sum(m => m.Points)
orderby TotalPoints descending
select new { User = g.Key, Username = g.Key.Username, TotalPoints };
entity.Results
.Where(m => m.Group == 0 || m.Group == 1)
.GroupBy(m => m.UserID)
.Select(m => new { User = m.Key, TotalPoints = m.Sum(v => v.Points) })
.OrderByDescending(m => m.TotalPoints);
Hi Vivendi use this(Please edit according to your requirement)
var q = (from h in entity.Results
group h by new { h.UserID} into hh
select new {
hh.Key.UserID,
Score = hh.Sum(s => s.Points )
}).OrderByDescending(i => i.Points);
Output
total: 17
total: 12
Another example with more than one sum and a join
from e in _context.LearnResults
join c in _context.Country on e.CountryId equals c.CountryId
where c.DomainId.Equals("xx")
group e by e.Country.Name into newCountry
let Approved = newCountry.Sum(e => e.Approved)
let Total = newCountry.Sum(e => e.Total)
select new LearnResults() { CountryName = newCountry.Key, Approved= Approved, Total=Total };

LINQ query with multiple join result represented as comma seperated results

The query below returns a list of leads joined to an "address" table, of where there can be multiple per lead.
I'm looking to return one response per lead, with addresses concatenated in the city view within the model and seperated by commas. If there are no cities in the join result, it should return '-'.
CURRENT OUTPUT
Company Name | Company City
===========================
Company 1 | Glasgow
Company 1 | London
Company 2 | London
Company 3 | NULL
DESIRED OUTPUT
===========================
Company 1 | Glasgow, London
Company 2 | London
Company 3 | -
QUERY
return (from t1 in db.Opportunities
from s1 in db.OpportunityStatus.Where(x => x.OpportunityStatus_ID == t1.StatusReason_ID)
from t2 in db.Leads.Where(x => x.Lead_ID == t1.Lead_ID)
from t3 in db.LeadAddresses.Where(x => x.Lead_ID == t2.Lead_ID).DefaultIfEmpty()
from t4 in db.Addresses.Where(x => x.Address_ID == t3.Address_ID).DefaultIfEmpty()
orderby (t1.Created) descending
select new FieldSalesPipelineViewModel
{
Id = t1.Opportunity_ID,
CompanyName = t2.Company_Name,
OpportunityTitle = t1.Opportunity_Title,
CompanyCity = "",
OpportunityStatusName = s1.OpportunityStatus_Name
}).Take(howMany);
Try a string-join:
CompanyCity = string.Join(",", (from p in db.Opportunities where t2.companyname == p.companyname select p.Companycity)
For your example:
return (from t1 in db.Opportunities
from s1 in db.OpportunityStatus.Where(x => x.OpportunityStatus_ID == t1.StatusReason_ID)
from t2 in db.Leads.Where(x => x.Lead_ID == t1.Lead_ID)
from t3 in db.LeadAddresses.Where(x => x.Lead_ID == t2.Lead_ID).DefaultIfEmpty()
orderby (t1.Created) descending
select new FieldSalesPipelineViewModel
{
Id = t1.Opportunity_ID,
CompanyName = t2.Company_Name,
OpportunityTitle = t1.Opportunity_Title,
CompanyCity = string.Join(",", (from t4 in db.Addresses Where t4.Address_ID == t3.Address_ID select t4.CompanyCity),
OpportunityStatusName = s1.OpportunityStatus_Name
}).Take(howMany);

Categories