使用 `groupjoin` 的查询无法翻译,尽管它被记录为受支持
Posted
技术标签:
【中文标题】使用 `groupjoin` 的查询无法翻译,尽管它被记录为受支持【英文标题】:Query with `groupjoin` cannot be translated although it's documened as being supported 【发布时间】:2021-06-24 21:59:04 【问题描述】:我不明白为什么这不能翻译。这似乎正是here 描述的用例。
LINQ 表达式
DbSet<A>()
.GroupJoin(
inner: DbSet<B>(),
outerKeySelector: a => a.AId,
innerKeySelector: b => b.AId,
resultSelector: (a, bs) => new
a = a,
bs = bs
)
产生错误:
无法翻译。以可翻译的形式重写查询,或通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用显式切换到客户端评估。请参阅https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。
产生异常的 LINQ 代码是
from a in ctx.As
join b in ctx.Bs on a.aId equals b.aId into bs
select new A = a, Bs = bs.ToList();
编辑:也许我误解了文档,这是一个不翻译的例子。
执行类似以下示例的查询会生成 Blog 和 IEnumerable 的结果。由于数据库(尤其是关系数据库)无法表示客户端对象的集合,因此 GroupJoin 在许多情况下不会转换为服务器。它要求您从服务器获取所有数据以在没有特殊选择器的情况下进行 GroupJoin(下面的第一个查询)。但是如果选择器限制了被选择的数据,那么从服务器获取所有数据可能会导致性能问题(下面的第二个查询)。这就是 EF Core 不翻译 GroupJoin 的原因。
但后来我的问题变成了:如何在不需要导航属性的情况下实现我正在寻找的结果?
【问题讨论】:
【参考方案1】:链接文档中的解释只是遵循 EF Core 团队的愿景并且很荒谬,因为它当然可以很容易地翻译 - 我在这里与团队进行了长时间的讨论 Query with GroupBy or GroupJoin throws exception #17068 并在此处继续 Query: Support GroupJoin when it is final query operator #19930,试图说服他们为什么应该支持它,不管争论如何,都没有运气。
重点是(这是当前的解决方法)它可以像关联子查询 (SelectMany
) 一样进行处理,并正确翻译和处理(即使查询结果形状没有 SQL 等效项。
无论如何,当前状态是“需要设计”(无论这意味着什么),解决方法是用相关子查询替换联接(这是 EF Core 在查询翻译期间“扩展”集合导航属性时在内部使用的)。
在你的情况下,替换
join b in ctx.Bs on a.aId equals b.aId into bs
与
let bs = ctx.Bs.Where(b => a.aId == b.aId)
但是,我强烈建议添加和使用导航属性。不知道为什么你“不能使用”它们,在 LINQ to Entities 中,它们不投射实体,它们只为关系提供元数据,从而自动生成必要的连接。通过不定义它们,您只是给自己施加了不必要的限制(除了 EF Core 限制/错误)。一般来说,当使用导航属性而不是手动连接时,EF Core 会更好地工作并支持更多的东西。
【讨论】:
谢谢,这似乎是我要找的。我不使用导航属性,因为它们至少在我的用例中容易出错。此外,我更喜欢使连接显式并具有更简单的实体类型 s.t.我没有忘记关系数据库管理的局限性【参考方案2】:试试这个查询,它应该适用于 EF Core:
var query =
from a in ctx.As
select new A = a, Bs = ctx.Bs.Where(b => b.Id == a.aId).ToList();
【讨论】:
【参考方案3】:.ToList()
可能无法翻译。改用包含
var result = ctx.As
.Include(a => a.Bs)
.ToList();
你必须为 A 类中的 B 提供导航属性:
public class A
public int aId get; set;
public List<B> Bs get; set;
见:
Eager Loading of Related Data Relationships - EF Core【讨论】:
很遗憾,我不能使用导航属性。让我尝试不使用ToList()
。编辑:删除 ToList() 并不能解决问题。以上是关于使用 `groupjoin` 的查询无法翻译,尽管它被记录为受支持的主要内容,如果未能解决你的问题,请参考以下文章
GroupJoin with list返回多个结果,而不是按结果附加列表