嵌套左连接的C#Linq表达式

时间:2015-03-17 14:17:46

标签: c# sql linq left-join

我希望在linq表达式中格式化嵌套的左连接。我已经下载了LINQPad4,但它似乎没有能力将SQL翻译成linq。

我不明白如何获得嵌套的左连接。我试过用'进入'操纵表达。条款没有用。


Linq表达

from cli in Clients
join er in EntityRelationships on cli.EGUID equals er.ParentID
join con in Contacts on er.ChildID equals con.EGUID

join erEmail in EntityRelationships on er.EGUID equals erEmail.ParentID into erIfAny
from r in erIfAny.DefaultIfEmpty()
join ea in EmailAddresses on r.ChildID equals ea.EGUID
join eaDefault in EntityDefaultValues on r.ID equals eaDefault.RelationshipID

where cli.ClientID == 6
select new
{
    ContactID = con.ContactID,
    ContactLastName = con.ContactLastName,
    ContactFirstName = con.ContactFirstName,
    ContactTitle = con.ContactTitle,
    EmailAddress = ea
}).Distinct()

生成以下SQL语句

DECLARE @p0 Int = 6

SELECT DISTINCT con.*, ea.*
FROM Clients AS cli
INNER JOIN EntityRelationships AS er ON cli.eGUID = er.ParentID
INNER JOIN Contacts AS con ON er.ChildID = con.eGUID

LEFT OUTER JOIN EntityRelationships AS erEmail ON er.eGUID = erEmail.ParentID
INNER JOIN EmailAddresses AS ea ON erEmail.ChildID = ea.eGUID
INNER JOIN EntityDefaultValues AS eaDefault ON erEmail.ID = eaDefault.RelationshipID

WHERE cli.ClientID = @p0

但是,我需要将左边的两个内部连接像这样包裹在左边。

DECLARE @p0 Int = 6

SELECT DISTINCT con.*, ea.*
FROM Clients AS cli
INNER JOIN EntityRelationships AS er ON cli.eGUID = er.ParentID
INNER JOIN Contacts AS con ON er.ChildID = con.eGUID

LEFT OUTER JOIN EntityRelationships AS erEmail
    INNER JOIN EmailAddresses AS ea ON erEmail.ChildID = ea.eGUID
    INNER JOIN EntityDefaultValues AS eaDefault ON erEmail.ID = eaDefault.RelationshipID
ON er.eGUID = erEmail.ParentID

WHERE cli.ClientID = @p0

我的linq表达式应该是什么样的?


编辑:

我不知道我能做到这一点,但我最后只是编写内联SQL。

var query = db.Database.SqlQuery<ContactViewModel>(
"select distinct con.*, ea.Value as EmailAddress " +
"from Clients AS cli " +
"join EntityRelationships AS er ON cli.eGUID = er.ParentID " +
"join Contacts AS con ON er.ChildID = con.eGUID " +
"left join EntityRelationships AS erEmail " +
    "join EmailAddresses AS ea ON erEmail.ChildID = ea.eGUID " +
    "join EntityDefaultValues AS eaDefault ON erEmail.ID = eaDefault.RelationshipID " +
"on er.eGUID = erEmail.ParentID " +
"where cli.ClientID=" + cID.ToString() + " " +
"order by con.ContactLastName, con.ContactFirstName");

1 个答案:

答案 0 :(得分:0)

人们试图让LINQ代码与他们习惯使用的SQL相匹配是一个非常常见的错误。由于SQL仅限于扁平化的结果集,而面向对象的代码可以代表更丰富的分层数据,因此,如果您在LINQ查询中可以更好地建模真正想要的东西。停止思考SQL方面的问题。

我不完全确定你在这里要做什么,但LINQ中的左外连接通常看起来像一个对象,其中一个属性上有其他对象:

from cli in Clients
where cli.ClientID == 6
join er in EntityRelationships on cli.EGUID equals er.ParentID
join con in Contacts on er.ChildID equals con.EGUID
select new
{
    ContactID = con.ContactID,
    ContactLastName = con.ContactLastName,
    ContactFirstName = con.ContactFirstName,
    ContactTitle = con.ContactTitle,
    Emails = 
        from erEmail in EntityRelationships
        where er.EGUID == erEmail.ParentID
        join ea in EmailAddresses on r.ChildID equals ea.EGUID
        where EntityDefaultValues.Any(eaDefault => r.ID == eaDefault.RelationshipID
        select ea
}