【问题标题】:Left Join in VB.NET LINQVB.NET LINQ 中的左连接
【发布时间】:2020-02-24 13:02:29
【问题描述】:

我正在尝试弄清楚如何在 Linq 中执行 LEFT JOIN,但遇到了困难......

我有一个现有的查询

Dim people As List(Of SimplePerson)

Using gpd As New peopleDatabase
    people = (From person In gpd.People Join office In gpd.Offices On person.office_ref Equals office.officeID
              Join personphone In gpd.x_PersonPhone On person.personId Equals personphone.person_ref
              Join telephoneNumber In gpd.TelephoneNumbers On personphone.telephoneNumber_ref Equals telephoneNumber.telephoneNumberId
              Where (person.preferredGivenName & " " & person.familyName).StartsWith(searchTerm) And telephoneNumber.x_TelephoneNumberTelephoneNumberType.FirstOrDefault.b_telephoneNumberType.telephoneNumberTypeId = 1 And person.active = True
              Select New SimplePerson() With {
                  .Name = person.preferredGivenName & " " & person.familyName,
                  .EmailAddress = person.emailAddress,
                  .Title = person.jobTitle_l,
                  .ResId = person.sourceKey,
                  .OrganisationId = person.organisation_ref.Value,
                  .OfficeName = office.name_l,
                  .TelephoneNumber = telephoneNumber.formattedNumberInternational
              }
          ).OrderBy(Function(n) n.Name).Take(20).ToList

End Using

Return people

对于上下文,这是我用于 jQueryUI 自动完成小部件的查询。 SimplePerson 是我正在使用的 POCO,它只包含上面代码中列出的一组属性。

我想要实现的是更改查询,以便它列出人们,无论他们是否有任何电话号码,即他们在表 x_PersonPhone 中没有条目。基于this answer,我相信 DefaultIfEmpty 会在某个地方出现,但我看不到如何将其应用于 x_PersonPhone,然后继续加入该表以获取匹配的行。

【问题讨论】:

    标签: vb.net linq left-join


    【解决方案1】:

    您应该按照链接的答案并使用Group Join。但是,就像您在 SQL 中继续在左连接依赖表之后使用 LEFT OUTER JOIN 一样,您需要先左连接 x_PersonPhone 和 TelephoneNumbers。而且由于您将加入两次,因此您不能只使用一个Group 关键字;你必须使用两个。请参阅此处的 Group By Clause 语法,特别是 Into <alias> = Group 构造。

    Dim people As List(Of SimplePerson)
    
    Using gpd As New peopleDatabase()
    
        people =
            (From person In gpd.People
                Join office In gpd.Offices On person.office_ref Equals office.OfficeID
                Group Join personphone In gpd.x_PersonPhone On person.PersonID Equals personphone.person_ref
                    Into g1 = Group From personphone In g1.DefaultIfEmpty()
                Group Join telephoneNumber In gpd.TelephoneNumbers On personphone.telephoneNumber_ref Equals telephoneNumber.telephoneNumberId
                    Into g2 = Group From telephoneNumber In g2.DefaultIfEmpty()
                Where (person.preferredGivenName & " " & person.familyName).StartsWith(searchTerm) _
                    And telephoneNumber.x_TelephoneNumberTelephoneNumberType.FirstOrDefault().b_telephoneNumberType.telephoneNumberTypeId = 1 _
                    And person.active = True
                Select New SimplePerson() With {
                    .Name = person.preferredGivenName & " " & person.familyName,
                    .EmailAddress = person.emailAddress,
                    .Title = person.jobTitle_l,
                    .ResId = person.sourceKey,
                    .OrganisationId = person.organisation_ref.Value,
                    .OfficeName = office.name_l,
                    .telephoneNumber = If(g2 Is Nothing, "No telephone", telephoneNumber.formattedNumberInternational)}
                ).OrderBy(Function(n) n.Name).Take(20).ToList()
    
    End Using
    
    Return people
    

    我无法真正测试这个。您可能需要将Select New SimplePerson() With { ... 中的行从

    .telephoneNumber = If(g2 Is Nothing, "No telephone", telephoneNumber.formattedNumberInternational)
    

    .telephoneNumber = If(telephoneNumber Is Nothing, "No telephone", telephoneNumber.formattedNumberInternational)
    

    如果可行,请告诉我,我会更新答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 2011-08-04
      • 2011-03-25
      相关资源
      最近更新 更多