【发布时间】:2011-07-08 12:54:35
【问题描述】:
我的 EF 模型的一部分如下所示:
总结:
- 位置有许多帖子
- Post 是一个抽象类
- 讨论派生来自帖子
- 讨论有很多评论
现在,我要实现的查询:
获取有关位置 ID 1234 的信息,包括与这些讨论相关的任何讨论和评论。
我可以得到这样的讨论和 cmets:
var discussions = ctx.Posts
.OfType<Discussion>()
.Include(x => x.Comments)
.ToList();
但我似乎无法根据 Location 实体上的 Posts 导航来获取它。
我试过了:
var locationWithDiscussionsAndComments = ctx
.Locations
.Include(x => x.Posts
.OfType<Discussion>()
.Select(y => y.Comments))
.SingleOrDefault();
编译,但我得到错误:
System.ArgumentException:包含路径表达式必须引用实体定义的属性,还可以选择嵌套属性或调用 Select。 参数名称:路径
有什么想法吗?我可能会从帖子中“倒退”:
var locationWithDiscussionsAndComments = ctx
.Posts
.Include(x => x.Location)
.OfType<Discussion>()
.Include(x => x.Comments)
.Where(x => x.LocationId == 1234)
.Select(x => x.Location)
.ToList();
但是就我的存储库而言,这既麻烦又在语义上是错误的(我不应该通过发布存储库来获取有关位置的信息)。
有什么想法吗?
编辑
所以在仔细考虑之后,我意识到OfType<T> 是一个过滤操作。正如我们所知,EF 不支持预加载过滤。唯一的选择是检索所有内容,或使用匿名类型投影。
我无法检索所有内容,因为涉及的元数据太多。所以我正在尝试匿名类型投影。
【问题讨论】:
-
是的,毕竟新的 Include 重载中的 Lambda 表达式只是一个属性选择器,您不能在其中包含任何类型的过滤逻辑。就像你提到的,你最好的选择是在这里使用匿名预测。你在这里使用 DbContext 吗?
-
@Morteza - 是的,我使用
DbContext,在Repository<T>后面,其中T是聚合根,Location和Post都是。所以单独的存储库。 -
好的,那么您可以使用新的 Query 方法在显式加载相关实体时应用过滤器(虽然它不是急切加载),如下所述:blogs.msdn.com/b/adonet/archive/2011/01/31/…
-
@Morteza - 我听说过,但我使用的是 POCO,所以
ctx.Posts是ICollection<Post>,而不是DbSet<T>。我将如何处理 POCO? -
你确定吗?我觉得应该是
ObjectSet<Post>?
标签: c# abstract-class eager-loading entity-framework-ctp5 navigational-properties