LINQ To Entities + Include + Анонимный тип
Рассмотрим:
Клиент класса
Проект класса
Билет класса
Ответ класса
У клиентов есть сводная коллекция проектов, у проектов есть сводная коллекция билетов, а у билетов есть сводная коллекция ответов.
var data = ctx.Set<Ticket>().Include(p => p.Client).
Select(p => new { Ticket = p, LastReplyDate = p.Replies.Max(q => q.DateCreated)});
Не работает. Ни один проект и клиент не загружаются при выборе данных таким образом.
Я знаю, как заставить его работать. Мой вопрос: почему он не работает так?
Ответы
Ответ 1
Как отметил Ладислав, Include
работает только при непосредственном выборе объекта Ticket
. Поскольку вы проецируете другую информацию, Include
игнорируется.
Это должно обеспечить хорошую работу:
var data = ctx.Set<Ticket>()
.Select(p => new
{
Ticket = p,
Clients = p.Client,
LastReplyDate = p.Replies.Max(q => q.DateCreated)
});
Прежде всего, каждый клиент Ticket будет доступен непосредственно из свойства Clients
в анонимном типе. Кроме того, Entity Framework должен быть достаточно умным, чтобы распознать, что вы вытащили всю коллекцию Client
для каждого Ticket
, поэтому вызов .Ticket.Client
также должен работать.
Ответ 2
Потому что Include
работает только при непосредственном выборе объектов. После выполнения проекции Include
игнорируется. Я не скажу вам, почему, но он просто работает таким образом.
Ответ 3
Другая возможность - использовать решение StriplingWarrior, но затем очистить промежуточные данные от конечного результата:
var data = ctx.Set<Ticket>()
.Select(p => new
{
Ticket = p,
Clients = p.Client,
LastReplyDate = p.Replies.Max(q => q.DateCreated)
})
.AsEnumerable()
.Select(p => new
{
Ticket = p.Ticket,
LastReplyDate = p.LastReplyDate
});