负载导航与过滤器属性实体框架4.3(load navigation properties with

2019-07-30 04:04发布

几天后,我提出一个问题,关于映射两类MessageMessageStatusHistory使用EF。 映射会很好,但我现在面临的一些问题与导航性能StatusHistoryMessage ,它涉及到MessageStatusHistory对象。 我加载的消息只有一个用户,并希望有关只有该用户的状态。 就像我会想显示用户是否已标记消息为已读/未读和时间。 如果我使用默认加载机制类似以下加载所有与用户无关的消息历史记录:

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()Histories = m.Histories.Where(x=> x.SenderId == userId).ToList()

Answer 1:

关于您编辑的部分:你不能使用ToList()的投影,只要把它的IEnumerable<T>并转换为一个List<T>当你构建的Message 。 你也不需要创建两个目录对象,可以从LINQ切换到实体查询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....



文章来源: load navigation properties with filter for Entity Framework 4.3