Группа Linq по нескольким полям в разных таблицах
в попытке преобразовать этот SQL-запрос в LINQ я столкнулся с проблемой group by. Как я могу группировать по нескольким столбцам, которые происходят из нескольких таблиц? Запрос linq ниже просто не будет компилироваться, поэтому мне нужен правильный синтаксис
оригинальный SQL-запрос
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
попытка запроса Linq (не работает)
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};
1 ответов
Для начала, ваш запрос не эквивалентен. Второстепенные вещи действительно любят разные значения, но главный из них заключается в том, что вы не группируете одни и те же ключи. SQL, сгруппированный по JobCode, который вы оставили в своем запросе. И ты пытался слишком много группировать вместо того, чтобы приказывать. Значения, которые вы агрегируете, должны быть тем, что вы группируете.
что касается того, почему вы получаете синтаксическую ошибку, после того, как вы делаете продолжение (используя into
на group by
или select
статья), все переменные в предыдущей области теряются, и остается только переменная продолжения (g1
в вашем случае). Вы пытались ссылаться e
теперь область дает вам проблемы.
запрос должен быть больше похож на это, я думаю:
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),
};