LINQ 组求和查询中的 Bool 到 int
Bool to int in a LINQ group sum query
我继承了一个应用程序,我需要添加一个新功能,但现有的数据库和应用程序设计不佳。
我需要使用 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))
};
在不更改数据库的情况下有任何建议或解决方法吗?
请注意,此查询 return 是一个 IQueryable
,因为我需要 return 分页结果集,因此我无法将实体转储到列表中,然后执行操纵数据。
更新
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]
If this lat one was an integer with 0 or 1 value, it'd have been very easy, just a sum of this field
嗯,您可以使用标准条件运算符轻松地将 bool
值转换为 0 或 1 int
值,例如
g.Sum(s => s.d.DownloadedByEmployee ? 1 : 0)
在 EF Core 5.0+ 中,您还可以使用条件计数(在 EF6 和 EF Core 5.0 之前的版本中,您只能使用条件求和):
g.Count(s => s.d.DownloadedByEmployee)
我继承了一个应用程序,我需要添加一个新功能,但现有的数据库和应用程序设计不佳。
我需要使用 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))
};
在不更改数据库的情况下有任何建议或解决方法吗?
请注意,此查询 return 是一个 IQueryable
,因为我需要 return 分页结果集,因此我无法将实体转储到列表中,然后执行操纵数据。
更新
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]
If this lat one was an integer with 0 or 1 value, it'd have been very easy, just a sum of this field
嗯,您可以使用标准条件运算符轻松地将 bool
值转换为 0 或 1 int
值,例如
g.Sum(s => s.d.DownloadedByEmployee ? 1 : 0)
在 EF Core 5.0+ 中,您还可以使用条件计数(在 EF6 和 EF Core 5.0 之前的版本中,您只能使用条件求和):
g.Count(s => s.d.DownloadedByEmployee)