2016-11-11 55 views
1

比方说,我有这个疑问在SQL:LINQ:将加入与左连接

SELECT 
    .... 
FROM 
    TableA a 
    JOIN TableB b on a.Id = b.Id 

我已经得到了工作得很好的LINQ查询:

var results = (from a in db.TableA 
       join b in db.TableB on a.Id equals b.Id 
       select new MyObject {...}).ToList(); 

但现在我想还要为组合添加左连接。在SQL中:

SELECT 
    .... 
FROM 
    TableA a 
    JOIN TableB b on a.Id = b.Id 
    LEFT JOIN TableC c on a.Id2 = c.Id2 

我不知道如何在linq查询中处理这个问题。

+0

只需在你的tableB连接后将一行添加到db.TableC上的a.Id中加入c等于c.Id' –

+0

即使TableC现在具有匹配的记录,它的行为就像是LEFT JOIN并包含TableA中的所有行(c .ID2为空)? –

+0

你知道如何编写[LINQ中的左外连接](https://msdn.microsoft.com/en-us/library/bb311040.aspx#Anchor_2),不是吗?就像在查询中没有其他连接一样编写它,例如'在a.Id2上的TableC中加入c等于c.Id2在ac.DefaultIfEmpty()中的c中加入ac' –

回答

1

SQL的LEFT JOIN概念是一个非常笨重的抽象,当你思考你真正想要做什么。对于每个TableA条目,您都希望拥有与其关联的TableC项目列表,对吗?

LINQ使用更简单的(IMO)方法来表示这种抽象,因为它具有嵌套层次对象的概念。提供程序将生成一个LEFT JOIN,但它也会将结果生成一个易于使用的对象结构。

var results = (from a in db.TableA 
       join b in db.TableB on a.Id equals b.Id 
       select new MyObject { 
        ... 
        TableCEntries = 
         from c in db.TableC 
         where c.Id == a.Id 
         select c  // or select specific values from c 
       }).ToList(); 

如果你真的想你的成绩平了路,他们将与左外连接,你可以这样做:

var results = (from a in db.TableA 
       join b in db.TableB on a.Id equals b.Id 
       from c in db.TableC 
       where c.Id == a.Id 
       select new MyObject { 
        ... 
       }).ToList(); 

...但你不会得到任何条目TableA,其中不存在TableC的条目。对于这种行为,你必须做group by/DefaultIfEmpty丑陋的东西,如Ivan Stoev's link所示。

+0

虽然这不等同于SQL'LEFT OUTER JOIN'。 –

+0

@IvanStoev:查看我的更新。 – StriplingWarrior

+0

我看到了(并且一般同意),但对于原始OP查询(a和b之间的连接)也可以这样说。连接和组连接之间的选择取决于查询作者。格特阿诺德的评论更有意义。只是一个想法:)顺便说一句,最后一次编辑是不正确的(与'where c.Id == a.Id') - 请参阅我的帖子下的帖子。 –