【问题标题】:LEFT LINQ TO SQL C# JOIN on many to many tableLEFT LINQ TO SQL C# JOIN 在多对多表上
【发布时间】:2024-05-03 16:50:02
【问题描述】:

嗨,我对 linq to sql 有点陌生,我了解基本知识。问题是我想在查询中进行左连接。查询中有 3 个表。

  1. 索赔人(应从该表返回所有行)
  2. 索赔
  3. 用户

查询应返回所有拥有索赔人的用户。这是通过多对多表声明完成的。但无论用户如何,都应退回所有索赔人。因此,Claimants 上的左连接。

我有以下问题

    var d = (from Claimants in DB.Claimants
                 join Claims in DB.Claims on Claimants.Claiment_ID equals Claims.Claiment_ID
                 join Users in DB.Users on Claims.User_ID equals Users.User_ID
                 where (Claimants.TrialDate.Value >= dtDayStart & Claimants.TrialDate <= dtDayEnd)
                 select new
                 {
                     ClaimantFirstName = Claimants.FirstName,
                     ClaimantLasname = Claimants.LastName,
                     ClaimantsID = Claimants.IDNumber,
                     Claimants.OurReference,
                     Claimants.TrialDate,
                     InterviewStart = Claims.DateTimeStart,
                     InterviewEnd = Claims.DateTimeEnd,
                     Claims.Priority,
                     UserFirstname = Users.FirstName,
                     UserLastName = Users.LastName,
                     UserID = Users.IDNumber
                 });

我尝试过如下使用 into 语句,但没有成功

        var d = (from Claimants in DB.Claimants
                 join Claims in DB.Claims on Claimants.Claiment_ID equals Claims.Claiment_ID
                 into TheClaimants
                 from Claims in TheClaimants.DefaultIfEmpty()

                 join Users in DB.Users on Claims.User_ID equals Users.User_ID
                 where (Claimants.TrialDate.Value >= dtDayStart & Claimants.TrialDate <= dtDayEnd)
                 select new
                 {
                     ClaimantFirstName = Claimants.FirstName,
                     ClaimantLasname = Claimants.LastName,
                     ClaimantsID = Claimants.IDNumber,
                     Claimants.OurReference,
                     Claimants.TrialDate,
                     InterviewStart = Claims.DateTimeStart,
                     InterviewEnd = Claims.DateTimeEnd,
                     Claims.Priority,
                     UserFirstname = Users.FirstName,
                     UserLastName = Users.LastName,
                     UserID = Users.IDNumber
                 });

如果有人能指出如何正确使用这些左右连接并解释其工作原理,我将不胜感激。非常感谢您。

【问题讨论】:

标签: c# linq linq-to-sql many-to-many


【解决方案1】:
var d = (from Claimants in DB.Claimants
  join Claims in DB.Claims on Claimants.Claiment_ID equals Claims.Claiment_ID)
  .DefaultIfEmpty()
  join Users in DB.Users on Claims.User_ID equals Users.User_ID
  where (Claimants.TrialDate.Value >= dtDayStart & Claimants.TrialDate <= dtDayEnd)
  .DefaultIfEmpty()
  select new
  {
    ClaimantFirstName = Claimants.FirstName,
    ClaimantLasname = Claimants.LastName,
    ClaimantsID = Claimants.IDNumber,
    Claimants.OurReference,
    Claimants.TrialDate,
    InterviewStart = Claims.DateTimeStart,
    InterviewEnd = Claims.DateTimeEnd,
    Claims.Priority,
    UserFirstname = Users.FirstName,
    UserLastName = Users.LastName,
    UserID = Users.IDNumber
 });

Left outter join

【讨论】:

    【解决方案2】:

    你一定认识一个鸾。如果您希望所有 Claiments 都返回,请从 Claiments 中选择开始,然后将其左连接到其他表。

    尝试以下方法:

    LINQ to SQL Left Outer Join

    【讨论】:

      【解决方案3】:

      在 LINQ 中,“.Join()”扩展方法相当于 SQL inner join

      对于外部联接,您必须使用“.GroupJoin()”扩展方法。

      假设您很了解 .Join,GroupJoin 使用起来很简单。我不得不承认,当我第一次需要在 LINQ 中进行外部连接时,很难找到。我无法想象他们为什么这样称呼它。

      虽然在 VB.Net 中,这里有一篇文章介绍了各种 SQL 构造翻译成 LINQ 语法,即使在 VB 中,仍然很容易转换为扩展方法:http://blogs.msdn.com/b/vbteam/archive/2007/12/31/converting-sql-to-linq-part-6-joins-bill-horst.aspx?Redirected=true

      编辑:@DavidB 在他的 cmets 中发布了一个更好的解决方案,但前提是您可以使用一些 ORM 导航属性。如果你没有它们,那么 GroupJoin 可能是最合理的

      【讨论】:

      • 之所以选择名称GroupJoin,是因为它实际上是连接和分组的混合体:左侧实体是键,每个实体都有一组(包含 0-n 个项目)右侧实体。当 linq 提供程序由 SQL 引擎支持时,它碰巧变成了外连接,但在 linq to objects 中,“GroupJoin”确实是对其功能的最佳描述。