Entity Framework — выполнение соединения, когда совпадение не всегда будет

#c# #entity-framework #linq

#c# #entity-framework #linq

Вопрос:

Я создаю запрос в entity framework, я пытаюсь выполнить правильное соединение, но это на дочернем объекте.

У меня есть таблица вызовов, которая регистрирует все телефонные звонки

 Call:    -Id-      -PhoneNumber-    -CallTime-  
          1         101             10
          2         102             20
          3         102             10 
 

Существует таблица PhoneNumbers, в которой есть телефонные номера известных номеров

    PhoneNumber:    -Id-      -PhoneNumber-    -PersonId-  
                    1         102             10
                    2         103             11
                    3         104             12 
 

И, наконец, есть таблица person, в которой есть имя, причина такой структуры в том, что у человека может быть много телефонных номеров.

    Person:         -Id-      -Name-       
                    10         John         
                    11         Paul             
                    12         George              
 

То, что я хочу, это список имен всех вызовов с указанием имени человека, если оно известно, вместо номера
, так что

 Call:    -Id-      -PhoneNumber-    -CallTime-  
          1         101               10
          2         John              20
          3         John              10 
 

Я пробовал следующее, но там настройка номера телефона не сработала, я знаю, что это соединение, но, похоже, не могу с этим справиться.

  var query = from call in Call    
                join phoneNumber in PhoneNumber on call.PhoneNumber              equals phoneNumber.PhoneNumber  
                join person      in Person  on phoneNumber.PersonID       equals person.Id  
                into r_join
                from rEmpty in r_join.DefaultIfEmpty()
                            
 select new {
               call.Id,
               PhoneNumber = rEmpty?.Name ?? call.Number
               call.CallTime
 }

 
 

Комментарии:

1. В чем проблема, с которой вы столкнулись с кодом — кажется, все в порядке.

Ответ №1:

Что я хочу, так это список имен для всех вызовов с именем пользователя, если оно известно, вместо номера, поэтому

Предполагая, что ваши телефонные номера уникальны:

 var result = dbContext.PhoneCalls.Select(phoneCall => new
{
    Id = phoneCall.Id,
    PhoneNumber = phoneCall.PhoneNumber,

    // from this phone call, get the corresponding item in table PhoneNumbers
    // from this PhoneNumber get the Person that the foreign key PersonId refers to
    // from this Person get the name
    PersonName = dbContext.PhoneNumbers
        .Where(phoneNumber => phoneNumber.PhoneNumber == phoneCall.PhoneNumber)
        .Select(phoneNumber => dbContext.Persons
                               .Where(person => person.Id == phoneNumber.PersonId)
                               .Select(person.Name))
        .FirstOrDefault();
});
 

Комментарии:

1. Спасибо, так оно и было, не уверен, что это вызовет у меня N 1 проблему, но список разбит на страницы …….. так что не буду об этом беспокоиться.