在 Linq 中加入、分组和求和

Join, Group by and Sum in Linq

我想通过employeeId对员工的加班时间进行分组,得到employeeNames的数据和员工每月的总加班时间。但是这个 Linq 查询给出了翻译错误。

var results = 
    from overtime in context.Overtimes
    join employeeCredential in context.EmployeeCredentials
        on overtime.EmployeeId equals employeeCredential.id
    join employeeDetail in context.EmployeeDetails
        on employeeCredential.id equals employeeDetail.employeeId
    where overtime.Month == month && overtime.Year == year
    group new { overtime, employeeCredential, employeeDetail } by overtime.EmployeeId into g
    select new MonthlyOvertimeWorkHours
    {
        EmployeeName = g.First().employeeDetail.employeeName,
        TotalWorkHourOfMonth = g.Sum(t => t.overtime.OvertimeWorkHour)
    };

错误

{ "error": employeeCredential\r\n IsNullable: True\r\n , \r\n employeeDetail = EntityShaperExpression: \r\n EntityType: EmployeeDetail\r\n ValueBufferExpression: \r\n ProjectionBindingExpression: employeeDetail\r\n IsNullable: True\r\n }\r\n .Select(s => s.employeeDetail.employeeName)\r\n .First()' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. }

在 EF Core 6 之前,您无法在分组后访问记录(这通常很糟糕)。只有聚合和 Key 可用。

要解决问题,只需将 employeeName 添加到分组键即可。

var results = 
    from overtime in context.Overtimes
    join employeeCredential in context.EmployeeCredentials
        on overtime.EmployeeId equals employeeCredential.id
    join employeeDetail in context.EmployeeDetails
        on employeeCredential.id equals employeeDetail.employeeId
    where overtime.Month == month && overtime.Year == year
    group new { overtime, employeeCredential, employeeDetail } by new { overtime.EmployeeId, employeeDetail.employeeName } into g
    select new MonthlyOvertimeWorkHours
    {
        EmployeeName = g.Key.employeeName,
        TotalWorkHourOfMonth = g.Sum(t => t.overtime.OvertimeWorkHour)
    };