Few days back I put a question regarding mapping two classes Message and MessageStatusHistory using EF. The mapping is going fine but I am facing some problems with the navigation property StatusHistory in class Message that relates it to MessageStatusHistory objects. I am loading the messages for one user only and want to the statuses pertaining to that user only. Like I would want to show if the user has marked message as read/not-read and when. If I use default loading mechanism like following it loads all the history related to the message irrespective of the user:
IDbSet<Message> dbs = _repo.DbSet;
dbs.Include("StatusHistory").Where(x=>x.MessageIdentifier == msgIdentifier);
To filter history for one user only I tried following trick:
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
I am getting the error:
The entity or complex type 'MyLib.Biz.Message' cannot be constructed in a LINQ
to Entities query.
I have tried by commenting StatusHistory = m.StatusHistory.Where(x => x.UserId == userId).ToList() also but it has not helped.
Please help me in getting Messages with filtered StatusHistory.
EDIT:- above is resolved with this code:
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();
But if I try to include replies to the message with:
from m in _repository.DBSet.Include("Replies").Include("Histories")
I am getting error on converting query to List with q.ToList() for Histories = m.Histories.Where(x=> x.SenderId == userId).ToList().
About your EDIT part: You cannot use
ToList()in a projection, just leave it anIEnumerable<T>and convert to aList<T>when you construct theMessage. You also don’t need to create two list objects, you can switch from the LINQ to Entities query to LINQ to Objects (the secondSelect) by usingAsEnumerable():Be aware that
Includehas no effect when you use a projection withselect. You need to make the properties that you want to include part of the projection – as you already did withselect new { Histories.....