Группа 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),
    };