LINQ - 使用group by和sum加入3个表

时间:2016-08-12 03:50:44

标签: c# linq join linq-to-sql group-by

我有以下SQL查询,我试图转换为LINQ:

Select Employee.Name,
       ts.HoursWorked,
       People.Date 
FROM [dbo].[HoursWorked] as Employee
JOIN (SELECT [Employee], Sum([LaborTime]) as HoursWorked
      FROM [dbo].[TimeSheet]
      GROUP BY [Employee] ) ts
ON Employee.Employee = ts.Employee
JOIN [dbo].[PeopleData] People
ON Employee.Employee = People.Employee

我已尝试过以下操作,但未返回预期结果:

from ts in _context.TimeSheet
join es in _context.HoursWorked on ts.Employee equals es.Employee
join ed in _context.EmployeeDetailed on ts.Employee equals ed.Employee
group ts by ts.Employee into g
select new 
{
    Name = g.Key,
    HoursWorked = g.Sum(e => e.LaborTime),
    FirstDate = ??? //Not sure how to access es
};

3 个答案:

答案 0 :(得分:1)

尝试以下查询。我已经改变了joins的顺序,只是为了保持它在你的SQL查询中。您尝试中缺少的部分是按名称分组,因为现在它不在嵌套查询中(如果您尝试执行此操作,则还必须执行此操作sql没有嵌套查询)

var result = from es in _context.HoursWorked
             join ts in _context.TimeSheet on es.Employee equals ts.Employee
             join ed in _context.EmployeeDetailed on es.Employee equals ed.Employee
             group ts by new { es.Name, ed.Date } into g
             select new
             {
                 Name = g.Key.Name,
                 FirstDate = g.Key.Date,
                 HoursWorked = g.Sum(e => e.LaborTime),
             };

如果你想像sql那样创建一个查询:

var result = from es in _context.HoursWorked
             join ts in _context.TimeSheet.GroupBy(item => item.Employee)
                                 .Select(g => new { Employee = g.Key, HourseWorked = g.Sum(item => item.LaborTime) })
             on es.Employee equals ts.Employee
             join ed in _context.EmployeeDetailed on es.Employee equals ed.Employee
             select new
             {
                 Name = es.Employee,
                 HoursWorked = ts.HourseWorked,
                 FirstDate = ed.Date
             };

在查询语法中:

var result = from es in _context.HoursWorked
             join ts in (from item in _context.TimeSheet
                         group item by item.Employee into g
                         select new { Employee = g.Key, HourseWorked = g.Sum(item => item.LaborTime) })
             on es.Employee equals ts.Employee
             join ed in _context.EmployeeDetailed on es.Employee equals ed.Employee
             select new
             {
                 Name = es.Employee,
                 HoursWorked = ts.HourseWorked,
                 FirstDate = ed.Date
             };

答案 1 :(得分:0)

您的一个join子句是一个子查询。为了使事情变得更容易,你应该分开:

var sub = from ts in _context.TimeSheet
          group ts by ts.Employee into g
          select new {
              Employee = g.Key,
              HoursWorked = g.Sum(p=>p.LaborTime)
          };

然后你可以这样做整个查询:

from emp in _context.HoursWorked
join s in sub on emp.Employee equals s.Employee
join pd in _context.PeopleData on emp.Employee equals pd.Employee
select new {emp.Name, s.HoursWorked, emp.FirstDate}

答案 2 :(得分:0)

在组范围变量之后,linq查询的任何局部变量都无法实现。因此,您无法访问在

之前声明的ed(ed.Date)变量
group ts by ts.Employee into g

此代码可以使用:

var result = ts in _context.TimeSheet
         group ts by ts.Employee into g
         let singleG = g.FirstOrDefault()
         join es in _context.HoursWorked  on singleG.Employee  equals  es.Employee
         join ed in _context.PeopleData on es.Employee equals ed.Employee 
         select new 
         {
          Name = g.Key,
          HoursWorked = g.Sum(e => e.LaborTime),
          FirstDate = ed.Date 
         };