LINQ左连接多个ON OR条件

时间:2016-11-23 06:55:27

标签: c# sql sql-server linq

我很遗憾告诉我LINQ上有点弱,在开始处理复杂的LINQ之前,我总是写SQL查询。

我想问一下如何将此SQL查询转换为LINQ LEFT JOIN,其中多个ON条件OR运算符。,

m.MerchandiseId将在ON状态下使用两次

SELECT
    *
FROM
    Inbox AS i
    INNER JOIN [User] AS u ON i.FromUserId = u.UserId
    LEFT OUTER JOIN Merchandise AS m ON
        u.MerchandiseId = m.MerchandiseId
        OR
        i.ToMerchantId = m.MerchandiseId
WHERE
    i.ToCompanyId = 10
    OR
    i.FromCompanyId = 10



var message = (from i in db.Inbox
               join u in db.User on i.FromUserId equals u.UserId
               join m in db.Merchandise on u.MerchandiseId equals m.MerchandiseId //here I want to ON i.MerchantId = m.MerchandiseId, but it doesn't allow
                where i.ToCompanyId == user.CompanyId || i.FromCompanyId == user.CompanyId
                orderby i.CreatedAt descending
                group m.MerchandiseId by new { m.MerchandiseId, m.MerchandiseName } into grp
                select new
                {
                       MerchandiseId = grp.Key.MerchandiseId,
                       MerchandiseName = grp.Key.MerchandiseName,
                       InboxMessage = (from e in db.Inbox
                                        join us in db.User on e.FromUserId equals us.UserId
                                         join mer in db.Merchandise on us.MerchandiseId equals mer.MerchandiseId
                                          where mer.MerchandiseId == grp.Key.MerchandiseId
                                          orderby e.CreatedAt descending
                                          select e.InboxMessage).FirstOrDefault(),
                       CreatedAt = (from e in db.Inbox
                                    join us in db.User on e.FromUserId equals us.UserId
                                    join mer in db.Merchandise on us.MerchandiseId equals mer.MerchandiseId
                                     where mer.MerchandiseId == grp.Key.MerchandiseId
                                     orderby e.CreatedAt descending
                                     select e.CreatedAt).FirstOrDefault(),
                                       }).ToList();

我为它写的底部LINQ查询。但是,我只能在LINQ中使用多个ON子句处理左连接。感谢有人会帮我这个。谢谢!

1 个答案:

答案 0 :(得分:4)

我不相信Linq支持使用多个列的OR运算符,但是,即使在SQL中我也不会使用OR,因为它会使联接的意图不明确也模糊了数据源自何处 - 如果每列有多个匹配项,也不会立即清楚会发生什么。相反,我会在不同的列上JOIN两次,让projection子句处理它:

SELECT
    *
FROM
    Inbox
    INNER JOIN [User] AS u ON i.FromUserId = u.UserId
    LEFT OUTER JOIN Merchandise AS userMerchant ON u.MerchandiseId = userMerchant.MerchandiseId
    LEFT OUTER JOIN Merchandise AS inboxMerchant ON Inbox.ToMerchantId = inboxMerchant .MerchandizeId
WHERE
    Inbox.ToCompanyId = 10
    OR
    Inbox.FromCompanyId = 10

然后可以使用LEFT OUTER JOIN方法(How to implement left join in JOIN Extension method)将其翻译成Linq

请注意,如果您正在使用Entity Framework,那么您根本不需要担心这样做!只需使用Include

var query = db.Inbox
    .Include( i => i.User )
    .Include( i => i.User.Merchandise )
    .Include  i => i.Merchandise )
    .Where( i => i.ToCompanyId = 10 || i.FromCompanyId == 10 );