#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