Entity framework 4 使用实体框架4.3的筛选器加载导航属性

Entity framework 4 使用实体框架4.3的筛选器加载导航属性,entity-framework-4,navigation-properties,Entity Framework 4,Navigation Properties,几天前,我提出了一个关于使用EF映射两个类Message和MessageStatusHistory的问题。映射进行得很顺利,但我在将导航属性StatusHistory与MessageStatusHistory对象关联的类Message中遇到了一些问题。我只为一个用户加载消息,只想查看与该用户相关的状态。我想显示用户是否已将消息标记为已读/未读以及何时。如果我使用如下默认加载机制,它将加载与消息相关的所有历史记录,而不考虑用户: IDbSet<Message> dbs = _repo.

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

IDbSet<Message> dbs = _repo.DbSet;
dbs.Include("StatusHistory").Where(x=>x.MessageIdentifier == msgIdentifier);
我也尝试过对StatusHistory=m.StatusHistory.Wherex=>x.UserId==UserId.ToList进行注释,但没有帮助

请帮助我获取具有过滤状态历史记录的邮件

编辑:-使用此代码解决上述问题:

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 Histories=m.Histories将查询转换为列表时出错。其中x=>x.SenderId==userId.ToList。

关于编辑部分:您不能在投影中使用ToList,只需将其保留为IEnumerable,并在构建消息时转换为列表即可。您也不需要创建两个列表对象,您可以从LINQ to Entities查询切换到LINQ to objects,然后使用可计算的:

var list=来自_repository.DBSet中的m 其中m.MessageIdentifier==id 选择新的{ // ... Histories=m.Histories.Wherex=>x.SenderId==userId } .AsEnumerable//在此执行数据库查询 .Selectm=>新消息{ // ... 历史=m.Histories.ToList, // ... }托利斯特先生; 退货清单;
请注意,将投影与“选择”一起使用时,“包含”无效。您需要创建要包含投影一部分的属性,就像您在“选择新”中所做的那样{Histories…

这不是StatusHistory。请参见例外:您不能在实体查询中创建实体对象。您必须创建镜像类型或匿名类型。感谢您的帮助。请回答一个小问题:为什么m.Histories.Wherex=>x.SenderId==userId.ToList在我只有.IncludeHistories而没有.IncludeR的情况下工作eplies也在这个查询中?@TheVillageIdiot:你确定第二个包含会有所不同吗?老实说,我希望在投影中使用ToList永远不会起作用,不管你是否有一个包含以及有多少个。它应该总是抛出臭名昭著的…无法将“ToList”翻译成存储表达式…例外。是的,你是对的。它是thro还有一个例外,我把ToList的另一个方法误认为是这个方法。
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")