Entity Framework 核心:如何将 2 个 COUNT 查询合并为一个
Entity Framework Core: How to combine 2 COUNT queries into one
我正在使用 Entity Framework Core 提高后端性能。这是一个小而简单的例子来说明我想要什么 return:
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)或者它实际上没有改进有什么吗?
谢谢
为了在 select 中进行多个顶级聚合,您必须根据常量值进行分组。
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();
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。
我正在使用 Entity Framework Core 提高后端性能。这是一个小而简单的例子来说明我想要什么 return:
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)或者它实际上没有改进有什么吗?
谢谢
为了在 select 中进行多个顶级聚合,您必须根据常量值进行分组。
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();
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。