Ядро Ef 3.1 Получение клиентов с дополнительными контактами

#lambda #entity-framework-core

#lambda #entity-framework-core

Вопрос:

У меня есть модель, в которой у клиента может быть 0 .. N контактов. Отношение контакта имеет ContactType. «Основной», «Получатель отчета» или «Не установлен».

0 = ‘не установлено’ 1 = ‘Основной контакт’ 2 = ‘Получатель отчета’

Я хотел бы иметь:

  • Все клиенты, даже если у них нет контакта
  • только основной контакт, если он есть. И если их два, то только первый (если это возможно).

Это то, что у меня есть прямо сейчас. Но, конечно, это вернет только клиентов с основным контактом.

 var customers= ctx.Customers
    .Include(x => x.CustomerContacts)
    .Where(x => x.CustomerContacts.Any(y => y.ContactTypeId == 1))
    .ToList();
  

На данный момент я создал представление со следующим sql:

 select c.ID CustomerId, c.NAME CustomerName, ctype.NAME CustomerType,   ct.NAME ContactName, ct.EMAIL ContactEmail, ct.PHONE ContactPhone from CUSTOMER c
left outer join CUSTOMER_TYPE ctype on c.CUSTOMER_TYPE_ID = ctype.ID
left outer join CUSTOMER_CONTACT_MAP map on c.id = map.customer_id and map.CONTACT_TYPE_ID = 1
left outer join CUSTOMER_CONTACT ct on ct.ID = map.CONTACT_ID
order by c.NAME;
  

Подсказка! Я думаю, что DefaultIfEmpty может быть ключом к решению проблемы внешнего соединения слева.

Я использую нового поставщика Oracle для ef core 3.1

Ответ №1:

Я думаю, что ваш наименее плохой вариант (помимо ожидания отфильтрованных включений в EF Core 5) — это запросить клиентов и основной контакт в отдельных свойствах объекта упаковки. Ваш запрос может выглядеть следующим образом:

 var results = ctx.Customers
     .Select(c => new {
        Customer = c,
        PrimaryContact = c.CustomerContacts.Where(cc => cc.ContactTypeId == 1).FirstOrDefault()
     }).ToList();
  

Вероятно, вам также следует указать, какой контакт типа 1 вы хотите получить, если существует более одного контакта, использующего OrderBy