【问题标题】:LINQ Left Join with multiple ON OR conditions具有多个 ON OR 条件的 LINQ Left Join
【发布时间】:2017-04-07 01:47:27
【问题描述】:

很抱歉,我在 LINQ 上有点薄弱,我总是在开始处理复杂的 LINQ 之前编写 SQL 查询。

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

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 子句处理左连接。感谢有人会在这方面帮助我。谢谢!

【问题讨论】:

  • @Sherlock 这不是重复的,您链接到的 Linq 查询有多个 AND,而不是 OR
  • @Dai 我没有说它是重复的 santosh singh 不是我评论的 :) 不要让我心脏病发作,还有链接,让他弄清楚发生了什么,这样他就可以学习了,我们需要弄脏我们的手才能学习而不是用勺子喂食
  • @Sherlock 正确检查我的查询,它不会重复,因为我在 stackoverflow 中找不到很多解决方案,我只是将它发布到这里。
  • @jefferyleo 我没有说它是重复的 santosh singh 说过的(他的评论已经被删除)。我提供的链接可作为您从哪里开始的提示。
  • @Sherlock 顺便感谢一下,但我的情况与其他人有点不同,我的 ON 条件是 3 个不同的列

标签: c# sql sql-server linq


【解决方案1】:

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

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

请注意,如果您使用的是实体框架,那么您根本不需要担心这样做!只需使用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 );

【讨论】:

  • +一个用于 EF 部分,我不知道这个:)。我也很高兴看到你是否可以在没有 EF 的情况下使用 linq 查询或 linq 扩展来翻译它
  • 是的,@Sherlock 也是如此,如果您可以将其转换为 linq 查询,那将是最好的
  • @Sherlock 有可能,但我现在太累了,我会为智力挑战试一试。请注意,我总是更喜欢扩展方法语法而不是“本机”Linq。
  • @Dai 我们是一样的,我讨厌 linq 查询语法
猜你喜欢
  • 2014-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-13
  • 2021-11-21
  • 2013-05-14
  • 2011-12-01
  • 2020-08-24
相关资源
最近更新 更多