使用Entity Framework Core进行左外连接

4

我正在尝试使用EF7(7.0.0-rc1-final)、vNext RC1(rc1-final)和SQL Server 2014执行左外连接请求。

数据库:

Pet:Id,Name

User:Id,Name,#PetId

这个可以正常工作:

var queryWorks = from u in _context.Users
                 join p in _context.Pets on u.PetId equals p.Id into pp
                 from p in pp.DefaultIfEmpty()
                 select new {
                     UserName = u.Name,
                     Pet = p
                 };

但是这个不起作用(消息=“序列中不包含任何元素”):

var queryFails = from u in _context.Users
                 join p in _context.Pets on u.PetId equals p.Id into pp
                 from p in pp.DefaultIfEmpty()
                 select new {
                     UserName = u.Name,
                     PetName = (p == null ? "NULL" : p.Name)
                 };

SQL Server Profile 2014向我展示第二个请求没有发送到SQL Server。为什么?


这个问题最近已经被修复了。问题是EF对于带有DefaultIfEmpty查询的一些假设是不正确的,如果想在DIE()调用之上组合任何东西,EF就会抛出异常。这个修复将在下一个版本或夜间构建中提供。 - Maurycy
1个回答

3
我认为你第二个查询中的投影部分 p.Name 没有被处理。
截至RC1,EF7还不知道如何进行左外连接。简而言之,他们知道正确处理这一点非常重要,并且正在努力解决。
github的问题3186中报告了这个问题,并且一些开发人员对此发表了评论。
我自己也发表了另一个类似于你的实例的评论。
合作者“maumar”指出:

问题是在 Linq(对象)中不存在 LOJ 的概念。

提出的解决方法是使用 SelectMany-GroupJoin-DefaultIfEmpty 组合来表示可选导航,然后将此模式折叠到我们的关系管道中的 LOJ 中。问题是这会创建更复杂的查询(主要是由于子查询的引入),并且目前无法解决大多数非平凡情况下的bug。在我们能够修复导航属性扩展的问题之前,这些bug需要得到解决。

我们确实将其视为高优先级bug,因为它可能返回不正确的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接