使用支持Core By转换的EF Core 2.1,但在我投影键值之后不支持。
我有一个查询,需要允许一定范围的分组类型和一定范围的聚合类型。
分组依据:年,年/月,年/月/日等
汇总依据:平均,总和,最小值,最大值等
我创建了两个from datetime import timedelta
cond1 = df.DateTime-df.DateTime.shift(1) > pd.Timedelta(15, 'm')
#OR
#15_min = df.DateTime.diff() > pd.Timedelta(minutes=15)
cond2 = df.location != df.location.shift(1)
session_id = (cond1|cond2).cumsum()
df['session_id'] = session_id.map(pd.Series(range(0,10000)))
语句,一个用于分组,一个用于聚合。我的问题是我无法推迟执行并在SQL中执行分组。如果不是,则结果数据集会很大。
这是一种合理的方法还是应该只使用原始查询?
这是根据需要进行延迟和分组的,但是键类型对于年份/月份是唯一的,并且如果我想按不同的分组方式,则无法为第二个switch
中的聚合提供通用的解决方案作为年/月/日。
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()
});
的密钥似乎可以确保分组发生在客户端。
答案 0 :(得分:3)
我能够在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
});
很奇怪,如果我为组密钥创建一个特殊的类,使其具有与匿名类型完全相同的属性,并将new { ... }
更改为new MyKeyType { ... }
,EF Core将切换到客户端评估。
很快,GroupBy
(不仅是)SQL翻译仍然不稳定。看起来我们必须等待3.0才能在该领域获得最终的改进。