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 个问题:

  1. 如何将最后一个查询翻译成 EntityFramework,以防止执行 2 个不同的 SQL 查询?
  2. 它会提高性能吗? (即:这是一个小例子,但我有很多查询需要改进,其中一些非常大,大部分查询都是相同的,除了一个条件,就像这个例子中的 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。