In an attempt to convert this SQL query to LINQ I have hit a problem with group by. How can I group by multiple columns that originate from multiple tables? The linq query below simply won't compile so I'm in need of the correct syntax
select LTRIM(RTRIM(e.Shortname))
Name, LTRIM(RTRIM(j.JobName))
JobName, j.JobCode,
SUM(Hours) Hours,
MAX(ce.LatestTimesheetEntry) LastTimeSubmitted
from TWCTL.TW.Postings p
join TWCTL.TW.Employees e on e.EmployeeId = p.EmployeeId
join TWCTL.TW.Jobs j on j.JobCode = p.JobCode
join CentralTimeEmployees.dbo.Employees ce on ce.CtEmployeeId = e.EmployeeId
where (e.CostCentreId = 1 or e.CostCentreId = 3)
and (p.TransactionDate >= '2012-01-01' and p.TransactionDate <= '2012-07-01')
and j.JobCode <> 'CTCIT00001'
and ce.DatabaseCode = 'CTL'
and (ce.CostCentreId = 1 or ce.CostCentreId = 3)
group by j.JobName, j.JobCode, Shortname
order by e.Shortname, j.JobName
var model =
from p in context.Postings
join e in context.Employees on p.EmployeeId equals e.EmployeeId
join j in context.Jobs on p.JobCode equals j.JobCode
join ce in context.CentralTimeEmployees on e.EmployeeId equals ce.CtEmployeeId
where (e.CostCentreId == 5 || e.CostCentreId == 3)
&& (p.TransactionDate >= fromDate
&& p.TransactionDate <= toDate)
&& j.JobCode != "CTCIT00001"
&& ce.DatabaseCode == "CTL"
&& (ce.CostCentreId == 1 || ce.CostCentreId == 3)
group j by new {j.JobName, j.JobCode} into g1
group e by e.Shortname into g2 <- doesnt work??
select
new ProjectHoursViewModel
{Posting = p, Job = g1.Key.JobName, Employee = e, CentralTimeEmployee = ce};
For starters, your query is not equivalent. Minor things really like different values being checked but a major one is that you don't group by the same keys. The SQL grouped by JobCode which you left out in your query. And you attempted to group too much instead of ordering it. The values you are aggregating should be what you are grouping.
As for why you're getting the syntax error, after you do a continuation (using into
in a group by
or select
clause), all the variables in the previous scope are lost and only the continuation variable remains (g1
in your case). You tried to reference e
which is now out of scope giving you the problem.
The query should be more like this I think:
var fromDate = new DateTime(2012, 1, 1);
var toDate = new DateTime(2012, 7, 1);
var query =
from p in dc.Postings
join e in dc.Employees on p.EmployeeId equals e.EmployeeId
join j in dc.Jobs on p.JobCode equals j.JobCode
join ce in dc.CentralTimeEmployees on e.EmployeeId equals ce.CtEmployeeId
where (e.CostCentreId == 1 || e.CostCentreId == 3) // the SQL tested 1 or 3
&& (p.TransactionDate >= fromDate && p.TransactionDate <= toDate)
&& j.JobCode != "CTCIT00001"
&& ce.DatabaseCode == "CTL"
&& (ce.CostCentreId == 1 || ce.CostCentreId == 3)
group new { ce.Hours, ce.LatestTimesheetEntry }
by new { j.JobName, j.JobCode, e.ShortName } into g
orderby g.Key.ShortName, g.Key.JobName
select new
{
Name = g.Key.ShortName.Trim(),
JobName = g.Key.JobName.Trim(),
JobCode = g.Key.JobCode,
Hours = g.Sum(x => x.Hours),
LastTimeSubmitted = g.Max(x => x.LatestTimesheetEntry),
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With