我正在尝试在EF核心3.1.1(使用MariaDB上的Pomelo适配器3.1.1)中实现可怕的GroupBy + First模式,该模式已经使用correlated subqueries具有出色的回答。但是,使用此替代方法时,EF拒绝以任何形式转换DateTime.Date
比较:
var query = from groupKey in _context.Message.Select(x => new { x.MessageType, x.CreatedAt.Date }).Distinct()
from entity in _context.Message
.Select(x => new { x.CreatedAt.Date, Value = x })
.Where(x => x.Value.MessageType == groupKey.MessageType && x.Date == groupKey.Date)
// after removing Date comparison, the query executes ^^^^^^^^^^^^^^^^^^^^^^^^^^
.OrderBy(x => x.Value.CreatedAt)
.Take(1)
select entity.Value;
以上查询的目的是每天选择每种类型的第一条消息,然后具体化结果。客户端评估是不可行的,因为每天有成千上万的消息。
如果删除x.Date == groupKey.Date
部分,查询将转换并成功执行。我也尝试过分别比较年/月/日,但结果是一样的-EF抛出异常。
如何更改查询以使其按所述方式工作?
例外情况与解决方法的问题几乎相同,无法翻译查询:
System.InvalidOperationException:LINQ表达式'(CROSS APPLY(投影映射: ( 选择顶部((1))((转换((m0.CreatedAt),(日期)))AS c),((m0.Id)),((m0.Text)),((m0.CreatedAt)) FROM(消息AS m0) 在((((((((CONVERT((m0.CreatedAt),(date)))==(tc)))||(((Equal((CONVERT((m0.CreatedAt),(date))))) &&(等于((tc))))))))&& ((((t.MessageType)==(m0.MessageType)))) 无法翻译ORDER BY(((m0.CreatedAt)ASC))AS t0))'。
考虑到预期的已翻译SQL非常琐碎,这是一个奇怪的LINQ表达式,下面的查询已经过测试,并且与LINQ应该完全相同:
SELECT *
from (select *,
ROW_NUMBER() over (partition by MessageType, YEAR(CreatedAt), MONTH(CreatedAt), DAY(CreatedAt) order by CreatedAt desc )
as rn from Message
) as byDay where byDay.rn = 1;