LINQ 组求和查询中的 Bool 到 int

Gio*_*iox 4 c# linq linq-to-entities entity-framework-core

我继承了一个应用程序,需要添加一个新功能,但现有数据库和应用程序的设计都很糟糕。

我需要使用 LINQ 查询提取所有员工及其文档数量以及已打开的文档数量。

为了对文档进行计数,我做了一个简单的操作count(),对于打开的数字,我有一个布尔字段,指示文档是否已打开。如果这个 lat 是一个值为 0 或 1 的整数,那就非常简单了,只需对该字段求和即可。

我也尝试使用布尔值来完成此操作,但失败了,因为我无法在 Linq-to-Entities 中使用 Convert.toInt32 :


var employees = from e in context.Employees
                join d in context.EmployeeDocuments on e.EmployeeId equals d.EmployeeId into dj
                from d in dj.DefaultIfEmpty()
                group new { e, d } by new { e.EmployeeId, e.FirstName, e.LastName, e.FiscalCode, e.IdentificationNumber, e.EmploymentStartDate } into g
                select new EmployeeListItem
                           {
                               EmployeeId = g.Key.EmployeeId,
                               FirstName = g.Key.FirstName,
                               LastName = g.Key.LastName,
                               FiscalCode = g.Key.FiscalCode,
                               IdentificationNumber = g.Key.IdentificationNumber,
                               EmploymentStartDate = g.Key.EmploymentStartDate.ToString("dd/MM/yyyy"),
                               DocumentCount = g.Count(),
                               DocumentOpened = g.Sum(s => Convert.ToInt32(s.d.DownloadedByEmployee))
                           };
Run Code Online (Sandbox Code Playgroud)

在不更改数据库的情况下有什么建议或解决方法吗?

请注意,此查询返回一个IQueryable,因为我需要返回分页结果集,因此我无法将实体转储到列表中然后对数据进行操作。

更新

Ivan 的解决方案是完美的,因为我仍然停留在 .Net Core 3.1 上,所以我需要使用条件总和,它在以下 SQL 查询中进行翻译:

SELECT [e].[EmployeeId], [e].[FirstName], [e].[LastName], [e].[FiscalCode], [e].[IdentificationNumber], [e].[EmploymentStartDate], COUNT(*), COALESCE(SUM(CASE
    WHEN [e0].[DownloadedByEmployee] = CAST(1 AS bit) THEN 1
    ELSE 0
END), 0)
FROM [Employees] AS [e]
LEFT JOIN [EmployeeDocuments] AS [e0] ON [e].[EmployeeId] = [e0].[EmployeeId]
GROUP BY [e].[EmployeeId], [e].[FirstName], [e].[LastName], [e].[FiscalCode], [e].[IdentificationNumber], [e].[EmploymentStartDate]
Run Code Online (Sandbox Code Playgroud)

Iva*_*oev 6

如果这个 lat 是一个值为 0 或 1 的整数,那就很简单了,只需该字段的总和

好吧,您可以使用标准条件运算符轻松将bool值转换为 0 或 1值,例如int

g.Sum(s => s.d.DownloadedByEmployee ? 1 : 0)
Run Code Online (Sandbox Code Playgroud)

在 EF Core 5.0+ 中,您还可以使用条件计数(在 EF6 和 EF Core 5.0 之前的版本中,您只能使用条件总和):

g.Count(s => s.d.DownloadedByEmployee)
Run Code Online (Sandbox Code Playgroud)