具有延迟执行和 SQL 侧分组的 EF Core Group By

EF Core Group By with Deferred Execution and SQL side grouping

使用 EF Core 2.1,它支持按翻译分组,但在我投射键值后不支持。

我有一个查询需要允许一系列分组类型和一系列聚合类型。

分组依据:年,Year/Month,Year/Month/天等

聚合依据:平均值、总和、最小值、最大值等

我创建了两个 switch 语句,一个用于分组,一个用于聚合。我的问题是我无法推迟执行并在 SQL 内执行分组。如果不是,则生成的数据集非常大。

这是一种合理的方法还是我应该只使用原始查询?

这是根据需要延迟和分组的,但密钥类型是 year/month 所独有的,如果我想分组,我无法为第二个 switch 中的聚合提供通用解决方案通过一些不同的东西,例如 year/month/day.

var query1 = series
     .GroupBy(k => new { k.Created.Year, k.Created.Month, });

var result1 = query1
    .Select(i => new { i.Key, Value = i.Average(a => a.DataValue) });

一旦您将密钥转换为字符串,就会在客户端进行分组:

var query2 = series
      .GroupBy(k => k.Created.Year.ToString());

var result2 = query2
    .Select(i => new { i.Key, Value = i.Average(a => a.DataValue) });

这也会导致客户端发生分组:

var query3 = series
     .GroupBy(k => new { k.Created.Year, k.Created.Month, })
     .Select(i => new
     {
         Key = $"{i.Key.Year}-{i.Key.Month}",
         Values = i.ToList()
     });

有什么办法可以完成我的查询吗?理想情况下,我需要一个通用的组键来对服务器端进行分组,或者需要一种基于查询中的函数传递聚合的方法。生成基于 string 的密钥似乎可以确保分组发生在客户端。

我能够在 EF Core 2.1(和 2.2)中获得 SQL 翻译的唯一方法是按复合 anonymous 类型分组,有条件地包括所需的数据部分:

bool includeYear = ...;
bool includeMonth = ...;
bool includeDay = ...;
bool includeHour = ...;

var query1 = series
    .GroupBy(e => new
    {
        Year = includeYear ? e.CreatedDate.Year : 0,
        Month = includeMonth ? e.CreatedDate.Month : 0,
        Day = includeDay ? e.CreatedDate.Day : 0,
        Hour = includeHour ? e.CreatedDate.Hour : 0
    });

奇怪的是,如果我为具有与匿名类型完全相同的属性的组键创建一个特殊的 class 并将 new { ... } 更改为 new MyKeyType { ... },EF Core 会切换到客户端评估.

不久,GroupBy(不仅如此)SQL 翻译仍然不稳定。看起来我们必须等待 3.0 才能最终在该领域得到改进。