Left Join в VB. NET LINQ - PullRequest
       46

Left Join в VB. NET LINQ

0 голосов
/ 24 февраля 2020

Я пытаюсь выяснить, как выполнить LEFT JOIN в Linq, но изо всех сил ...

У меня есть существующий запрос

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. Основываясь на этом ответе , я полагаю, что DefaultIfEmpty где-то входит в него, но я не могу понять, как применить это к x_PersonPhone и затем продолжить присоединение к этой таблице для соответствующих строк.

1 Ответ

0 голосов
/ 24 февраля 2020

Вы должны следовать связанному ответу и использовать Group Join. Однако, так же, как вы продолжаете LEFT OUTER JOIN в SQL после левой зависимой таблицы, вам нужно присоединиться слева как к 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)

Если это сработает, пожалуйста, дайте мне знать, и я обновлю ответ.

...