使用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才能最终在该领域得到改进。