Val*_*tor 8 c# linq entity-framework-core
我有一个查询来查看用户插入了多少个实体 ( Version = 1) 以及他们更新了多少个实体( Version > 1)。它通过记录的用户名查询整个表和组。这是原始 SQL 查询:
SELECT
[s.InternalUser].[UserName],
COUNT(CASE WHEN s.Version = 1 THEN 1 END) AS [InsertCount],
COUNT(CASE WHEN s.Version > 1 THEN 1 END) AS [UpdateCount]
FROM [Sale] AS [s]
INNER JOIN [InternalUser] AS [s.InternalUser] ON [s].[InternalUserId] =
[s.InternalUser].[InternalUserId]
GROUP BY [s.InternalUser].[UserName]
Run Code Online (Sandbox Code Playgroud)
这将返回我想要的。我尝试将其转换为使用 EF Core 2.2 的项目中的 Linq 查询:
var countData = await _context.Sale
.GroupBy(s => s.InternalUser.UserName)
.Select(g => new
{
UserName = g.Key,
InsertCount = g.Count(s => s.Version == 1),
UpdateCount = g.Count(s => s.Version > 1)
})
.ToListAsync();
Run Code Online (Sandbox Code Playgroud)
然而,这会导致整个表被加载并在内存中完成计算:
Microsoft.EntityFrameworkCore.Query:警告:LINQ 表达式“GroupBy([s.InternalUser].UserName, [s])”无法翻译,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:警告:LINQ 表达式“where ([s].Version == 1)”无法翻译,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:警告:无法翻译 LINQ 表达式“Count()”,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:警告:LINQ 表达式“where ([s].Version == 1)”无法翻译,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:警告:无法翻译 LINQ 表达式“Count()”,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:Warning: The LINQ expression 'where ([s].Version > 1)' 无法翻译,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:警告:无法翻译 LINQ 表达式“Count()”,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:警告:LINQ 表达式“where ([s].Version > 1)”无法翻译,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:警告:无法翻译 LINQ 表达式“Count()”,将在本地进行评估。无法翻译,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:警告:无法翻译 LINQ 表达式“Count()”,将在本地进行评估。无法翻译,将在本地进行评估。Microsoft.EntityFrameworkCore.Query:警告:无法翻译 LINQ 表达式“Count()”,将在本地进行评估。
这Count()是导致它的查询,如果我删除 Group By 被转换为查询。
是否有不同的编写方式可以转换为我之前发布的 SQL 查询之类的内容?
Iva*_*oev 15
避免谓词版本Count并使用等效的条件Sum。
在 EF Core 3.0+ 中,您可以直接替换Count(condition)为Sum(condition ? 1 : 0),例如
var countData = await _context.Sale
.GroupBy(s => s.InternalUser.UserName)
.Select(g => new
{
UserName = g.Key,
InsertCount = g.Sum(s => s.Version == 1 ? 1 : 0),
UpdateCount = g.Sum(s => s.Version > 1 ? 1 : 0),
})
.ToListAsync();
Run Code Online (Sandbox Code Playgroud)
EF Core 2.x 仅支持GroupBy对简单分组元素属性访问器上的聚合进行转换,因此您需要使用GroupBy带元素选择器的重载来预选所需的表达式,例如
var countData = await _context.Sale
.GroupBy(s => s.InternalUser.UserName, s => new
{
InsertCount = s.Version == 1 ? 1 : 0,
UpdateCount = s.Version > 1 ? 1 : 0,
})
.Select(g => new
{
UserName = g.Key,
InsertCount = g.Sum(s => s.InsertCount),
UpdateCount = g.Sum(s => s.UpdateCount),
})
.ToListAsync();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3712 次 |
| 最近记录: |