LINQ 子查询的 Where 条件无法被翻译

18 浏览
0 Comments

LINQ 子查询的 Where 条件无法被翻译

我正在将这个查询转换为EF Core 2.2中的linq,但是我找不到任何正确的方法:

从Planning.RefineryUnitMonthDatas r中选择r.*,v.* 
join Planning.RefineryUnitMonthDataValues v on r.Id = v.EntityId 
join(
    从Planning.RefineryUnitMonthDatas r中选择EntityId, max(v.CreatedAt) CreatedAt 
    join Planning.RefineryUnitMonthDataValues v on r.Id = v.EntityId 
    where RefineryUnitId = @refinery and Date / 100 = @date 
    分组EntityId
) t on r.Id = t.EntityId 
where t.CreatedAt = v.CreatedAt

这是我的linq:

从db.RefineryUnitMonthDatas中的s中选择
join db.RefineryUnitMonthDataValues中的v on s.Id equals v.EntityId
join db.RefineryUnitMonthDatas中的r in (
  从db.RefineryUnitMonthDatas中的r中选择
  join db.RefineryUnitMonthDataValues中的v on r.Id equals v.EntityId
  where r.RefineryUnitId == refinery && r.Date / 100 == date
  按v.EntityId分组 into g
  选择新的{ g.Key, CreatedAt = g.Max(s => s.CreatedAt) }
) on s.Id equals r.Key
where r.CreatedAt == v.CreatedAt
选择新的{ s, v }

这个工作是正确的,但是存在性能问题,并且最后的Where子句没有转换为SQL。它会提示:

LINQ表达式'where ([r].CreatedAt == [v].CreatedAt)'无法被转换,将在本地评估

Core 2.2是否支持子查询的Where子句,还是我在某个地方犯了错误?

0
0 Comments

LINQ Subquery Where Clause could not be translated的问题出现的原因是EFC 2.2查询转换器的错误/缺陷/不足之一。在EFC 3.1中,该问题得到了解决。

在所有的“查询模式”中,我找到的唯一有效的方法是将谓词推入到join子句中,例如用以下内容替换:

) on s.Id equals r.Key
where r.CreatedAt == v.CreatedAt

替换为以下内容:

) on new { Key = s.Id, v.CreatedAt } equals new { r.Key, r.CreatedAt }

当然,这个解决方法只适用于可以转换为等值连接==比较。

感谢您的回复,我升级到了Core 3.1并进行了检查,Where子句在EFC 3.1中仍然无法工作,但等值连接方法在EFC 3.1中已经修复了。

嗨,对我来说,它完全按照我解释的方式工作。当然,我已经用我认为相似的查询进行了测试,因为您没有包含您的模型类。不幸的是,对于EF Core查询转换器在不同EFC版本之间的测试实际上是一种试错方法,必须在每个新版本中重新测试(他们修复了一些问题,但破坏了另一些问题等等)。请注意,在3.x中,许多在2.x中由客户端评估引起的低效问题现在是运行时异常。

0