具有延迟执行和SQL侧分组的EF核心分组依据



使用EF Core 2.1,它确实支持Group By翻译,但在我投影键值之后不支持。

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

分组依据:年、年、月、年、日等

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

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

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

这是推迟的,并根据需要进行分组,但密钥类型是年/月独有的,如果我想按不同的东西(如年/月/日(进行分组,我无法为第二个switch中的聚合提供通用解决方案。

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翻译的唯一方法是按复合匿名类型分组,有条件地包括所需的数据部分:

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
});

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

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

最新更新