0

几天前,我提出了一个关于映射两个类MessageMessageStatusHistory使用 EF 的问题。映射进展顺利,但我StatusHistory在类中将导航属性MessageMessageStatusHistory对象相关联时遇到了一些问题。我只为一个用户加载消息,并且只想要与该用户有关的状态。就像我想显示用户是否将消息标记为已读/未读以及何时。如果我使用如下默认加载机制,它将加载与消息相关的所有历史记录,而与用户无关:

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 的消息。

编辑:-上面是用这个代码解决的:

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()使用for将查询转换为 List 时出现错误Histories = m.Histories.Where(x=> x.SenderId == userId).ToList()

4

1 回答 1

0

关于您的 EDIT 部分:您不能ToList()在投影中使用,只需将其保留IEnumerable<T>为 a 并List<T>在构建Message. 您也不需要创建两个列表对象,您可以使用以下命令从 LINQ to Entities 查询切换到 LINQ to Objects(第二个SelectAsEnumerable()

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.....

于 2012-07-01T09:38:30.743 回答