2012-06-27 5 views
0

Несколько дней назад я поставил question относительно сопоставления двух классов Message и MessageStatusHistory с использованием EF. Отображение идет хорошо, но я сталкиваюсь с некоторыми проблемами с навигационным свойством StatusHistory в классе Message, который связывает его с объектами MessageStatusHistory. Я загружаю сообщения только для одного пользователя и хочу только статусы, относящиеся только к этому пользователю. Например, я хотел бы показать, имеет ли пользователь отмеченное сообщение как прочитанное/нечитаемое и когда. Если я использую механизм загрузки по умолчанию, как после него загружает всю историю, связанную с сообщением независимо от пользователя:Загрузка свойств навигации с фильтром для Entity Framework 4.3

IDbSet<Message> dbs = _repo.DbSet; 
dbs.Include("StatusHistory").Where(x=>x.MessageIdentifier == msgIdentifier); 

Чтобы отфильтровать историю только для одного пользователя, я попытался следующий трюк:

IDbSet<Message> dbs = _repo.DbSet; 
var q = from m in dbs.Include("StatusHistory") 
     where m.MessageIdentifier == msgIdentifier 
     select new Message 
     { 
      MessageIdentifier = m.MessageIdentifier, 
      /*OTHER PROPERTIES*/ 
      StatusHistory = m.StatusHistory 
          .Where(x => x.UserId == userId).ToList() 
     }; 

return q.ToList();//THROWING ERROR ON THIS LINE 

Я получаю сообщение об ошибке:

The entity or complex type 'MyLib.Biz.Message' cannot be constructed in a LINQ 
to Entities query. 

Я пытался, комментируя StatusHistory = m.StatusHistory.Where(x => x.UserId == userId).ToList() также, но это не помогло.

Пожалуйста, помогите мне в получении сообщений с фильтром StatusHistory.

EDIT: - выше решаются с этим кодом:

var q = from m in _repository.DBSet.Include("Histories") 
     where m.MessageIdentifier == id 
     select new { 
        m.Id,/*OTHER PROPERTIES*/ 
        Histories = m.Histories.Where(x => 
            x.SenderId == userId).ToList() 
        }; 

var lst = q.ToList(); 
return lst.Select(m => new Message{ 
      Id = m.Id, MessageIdentifier = m.MessageIdentifier, 
      MessageText = m.MessageText, Replies = m.Replies, 
      ReplyTo = m.ReplyTo, Histories = m.Histories, SenderId = 
      m.SenderId, SenderName = m.SenderName, CreatedOn = m.CreatedOn 
     }).ToList(); 

Но если я пытаюсь включить ответы на сообщения с:

from m in _repository.DBSet.Include("Replies").Include("Histories") 

Я получаю сообщение об ошибке на преобразование запроса Список с q.ToList() для Histories = m.Histories.Where(x=> x.SenderId == userId).ToList().

+1

Это не статусная история. См. Исключение: вы не можете создавать объекты сущности в запросе сущности. Вам нужно будет создать тип зеркала или анонимный тип. –

ответ

0

Об ПРАВКА части: Вы не можете использовать ToList() в проекции, просто оставить его в IEnumerable<T> и преобразовать в List<T> когда вы строите Message. Вам также не нужно, чтобы создать два списка объектов, вы можете перейти от LINQ к Entities запроса в LINQ к объектам (второй Select) с помощью AsEnumerable():

var list = (from m in _repository.DBSet 
      where m.MessageIdentifier == id 
      select new { 
       // ... 
       Histories = m.Histories.Where(x => x.SenderId == userId) 
      }) 
      .AsEnumerable() // database query is executed here 
      .Select(m => new Message { 
       // ... 
       Histories = m.Histories.ToList(), 
       // ... 
      }).ToList(); 

return list; 

Имейте в виду, что Include не имеет никакого эффекта, когда вас используйте проекцию с select. Вам нужно сделать свойства, которые вы хотите включить в часть проекции, как вы уже делали с select new { Histories.....

+0

спасибо за помощь. просто вопрос: почему «m.Histories.Where (x => x.SenderId == userId) .ToList()' работает, если у меня есть только '.Include (« Истории »)', а не когда у меня есть '. Включить («Ответы») 'также в запрос? – TheVillageIdiot

+1

@ TheVillageIdiot: Вы уверены, что второй 'Include' имеет значение? Я честно ожидаю, что использование 'ToList()' в проекции никогда не будет работать, независимо от того, есть ли у вас 'Include' и сколько. Он всегда должен бросать печально известный «... не может перевести исключение« ToList »в выражение store ...». – Slauma

+0

Да, вы правы. Это тоже исключение. Я принял другой метод для этого (с 'ToList'). – TheVillageIdiot

Смежные вопросы