2011-08-23 2 views
11

Рассмотрим:LINQ To Entities + Включить + анонимный тип вопроса

Client Class

Проект Класс

билет класса

Класс Ответить

Клиенты имеют коллекцию суб проектов, у проектов есть сводная коллекция билетов, а билеты имеют подзаголовок ответов.

var data = ctx.Set<Ticket>().Include(p => p.Client). 
Select(p => new { Ticket = p, LastReplyDate = p.Replies.Max(q => q.DateCreated)}); 

Не работает. Ни один проект, ни клиент не загружаются при выборе данных таким образом.

Я знаю, как заставить его работать. Мой вопрос: почему он не работает так?

ответ

10

Как отметил Ладислав, Include работает, только если вы выберите объект Ticket. Поскольку вы проецируете другую информацию, Include игнорируется.

Это должен обеспечить хорошую работу вокруг:

var data = ctx.Set<Ticket>() 
    .Select(p => new 
     { 
      Ticket = p, 
      Clients = p.Client, 
      LastReplyDate = p.Replies.Max(q => q.DateCreated) 
     }); 

Прежде всего, клиенты каждого билета будут доступны прямо из Clients собственности на анонимном типе. Кроме того, Entity Framework должен быть достаточно умным, чтобы признать, что вы вытащили всю коллекцию Client для каждого Ticket, поэтому необходимо также позвонить .Ticket.Client.

+0

Спасибо. Это тоже решение, о котором я думал. – Jeroen

+2

+1 для фактического предоставления решения :) – bernhof

+0

Я должен указать всем, кто читает это решение, что EF не волшебным образом заполняет свойство навигации .Ticket.Client' с объектами, возвращаемыми с этой проекцией, поэтому доступ к клиентам через объект Ticket снова запросит базу данных. –

5

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

+0

Как вы думаете, Microsoft планирует изменить это? – billy

+0

plus1 * Я не скажу вам, почему, но он просто работает таким образом. * –

2

Другая возможность заключается в использовании решение 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 
     });