Entity Framework Core:如何将 2 个 COUNT 查询合并为一个
Posted
技术标签:
【中文标题】Entity Framework Core:如何将 2 个 COUNT 查询合并为一个【英文标题】:Entity Framework Core: How to combine 2 COUNT queries into one 【发布时间】:2021-12-19 00:31:53 【问题描述】:我正在努力使用 Entity Framework Core 提高后端性能。这是一个小而简单的例子来说明我想要返回的内容:
var filteredMovies = _dataService
.Repository
.Where(movie => movie.Genre == 'Drama')
.Where(...many other conditions, joins, etc...);
var counts1 = filteredMovies.Count(movie => movie.director == 'Spielberg');
var counts2 = filteredMovies.Count(movie => movie.director == 'Nolan');
return new Summary
SpielbergCount = counts1,
NolanCount = counts2,
;
这将生成 2 个 SQL 查询,每个查询都经过所有 WHERE、JOIN 步骤。 我在 SQL 中看到的是,我可以这样写,只执行 1 个查询:
SELECT
SUM(CASE WHEN Director = 'Spielberg' THEN 1 ELSE 0 END) SpielbergCount,
SUM(CASE WHEN Director = 'Nolan' THEN 1 ELSE 0 END) NolanCount
FROM Movies
JOIN ....
WHERE ....
2 个问题:
-
如何将最后一个查询转换为 EntityFramework,以防止执行 2 个不同的 SQL 查询?
它会提高性能吗? (即:这是一个小例子,但我有很多查询需要改进,其中一些非常大,大多数查询是相同的,除了一个条件,如本例中的 Director)或者它实际上没有改进有什么?
谢谢
【问题讨论】:
基本上你必须做一个GroupBy
,你在一个常数值上分组,这样你就可以在你的Select
中做不同的总和。
【参考方案1】:
为了在一个选择中进行多个***聚合,您必须对一个常量值进行分组。
var counts = _dataService
.Repository
.Where(movie => movie.Genre == 'Drama')
.Where(...many other conditions, joins, etc...)
.GroupBy(x => 1)
.Select(grp => new Summary
SpielbergCount = grp.Count(movie => movie.director == 'Spielberg'),
NolanCount = grp.Count(movie => movie.director == 'Nolan'),
)
.Single();
【讨论】:
Hey juharr,您可以在@SupriyoDas 的帖子中看到回复,因为你们俩的解决方案非常相似!谢谢 @NicolasDontigny 请注意,通过对常量值进行分组,结果选择将只有一行,如果需要,您可以执行Single
。就性能而言,它实际上取决于您的表的设置方式,但这会将其减少到一个查询,而不是通常性能更高的 2 个。【参考方案2】:
return _dataService
.Repository
.Where(movie => movie.Genre == 'Drama')
.Where(movie => movie.director == 'Spielberg' || movie.director == 'Nolan')
.Where(...many other conditions, joins, etc...)
.GroupBy(movie => movie.director)
.Select(g => new Summary
SpielbergCount = g.Count(x => x.director == 'Spielberg'),
NolanCount = g.Count(x => x.director == 'Nolan'),
);
1.如何将最后一个查询转换为 EntityFramework,以防止执行 2 个不同的 SQL 查询?
尝试使用 Group By 和 Count with Filter。
2。它会提高性能吗?或者它实际上并没有改善什么?
提高性能的一些技巧
如果不需要,请避免获取所有字段 仅检索所需数量的记录 如果您想将处理从 SQL 服务器转移到应用程序服务器,请尝试使用 AsEnumerable。【讨论】:
但是与SQL中的SUM相反,根据我的理解,这将返回一个Summary对象的列表,因为GroupBy。 SQL 查询等效项将是 SELECT TOP(1) COUNT(...), COUNT(...) 而不仅仅是 SELECT COUNT(...), COUNT(...) 所以,我将不得不申请 .FirstOrDefault () 在获得 2 个计数之前对该对象进行处理,这似乎不是最佳实践,您怎么看?我什至可以通过应用它来提高性能吗? 这将产生 2 行,其中 Spielberg 行的 SpeilbergCount 和 NolanCount 将为 0,而 Nolan 行的 NolanCount 和 SpeilbergCount 将为 0。这就是您需要分组的原因而是一个常量值。以上是关于Entity Framework Core:如何将 2 个 COUNT 查询合并为一个的主要内容,如果未能解决你的问题,请参考以下文章
如何将 MySQL 与 .NET Core 3 和 Entity Framework 6 集成
如何将 C# 8.0 可空引用类型与 Entity Framework Core 模型一起使用?
如何使用 Entity Framework Core 正确保存 DateTime?
如何将 Sql 查询转换为 Linq 及其在 Entity Framework Core 中的 Join() 方法的等价物