在 Entity Framework 4.1 中查询实体的子集合
我有一组从 DbContext 中的 IDbSet 查询的实体。我现在想要迭代每个实体并查询它们的子集合,这些子集合在实体中定义为 ICollection。在子集合上调用 AsQueryable() 并对其运行 linq 查询是否正确?如果是这样,我的查询是 linq-to-objects 还是 EF 填充的集合对象是否实现了访问数据库的 IQueryable?
感谢您对此的任何见解。
I have a set of entities that I have queried from IDbSet in my DbContext. I now want to iterate over each entity and query their child collections, which are defined in the entity as ICollection. Is it correct to call AsQueryable() on the child collections and run my linq query on that? If so, will my queries be linq-to-objects or does the collection object populated by EF implement IQueryable that goes to the database?
Thanks for any insight on this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这完全取决于您的实体的定义方式以及是否启用了延迟加载。您对
IDbSet
的查询将是 linq-to-entities。如果启用延迟加载,则访问已加载实体的每个导航属性将触发数据库查询,该查询将加载所有相关实体。AsQueryable
在这里不起作用,您仍然会对所有加载的数据执行 linq-to-objects 查询。在这种情况下,使用预先加载并将相关实体与主实体一起加载确实是更好的方法:在某些情况下,执行此查询可以在内部生成 非常大的结果集。
如果您有很多相关实体,并且确实只想加载一些非常小的子集,则可以使用以下方法:
这是强制 EF 使用 linq-to-entities 只加载相关实体子集的方法。您仍然必须为每个加载的主实体执行此操作。执行如此多的查询非常慢。这仍然是N+1问题。
另一个最复杂的优化是加载单个查询中的所有主要实体以及另一个查询中的所有相关实体:
执行两个查询后,实体框架应确保导航属性正确填充相关实体,但这仅在关闭延迟加载时有效但实体是通过上下文进行跟踪的(我从未使用 DbContext API 尝试过此操作,但它可以与 ObjectContext API 一起使用)。
It whole depends on how your entities are defined and if lazy loading is enabled. Your query to
IDbSet
will be linq-to-entities. If lazy loading is enabled accessing each navigation property of the loaded entity will trigger database query which will load all related entities.AsQueryable
has no effect here you will still execute linq-to-objects query on all loaded data. In such scenario it is really better approach to use eager loading and load your related entities together with the main entity:In some cases executing this query can internally produce very big result sets.
If you have a lot of related entities and you really want to load only some very small subset you can use following approach:
This the way to force EF to load only subset of related entities with linq-to-entities. You still have to execute this for each loaded main entity. Executing so many queries is very slow. It is still N+1 problem.
Another and most complex optimization is loading all main entities in the single query and all related entities in another query:
Once you execute both queries Entity framework should ensure that navigation properties are correctly filled with related entities but this works only when lazy loading is turned off but entities are tracked by context (well I never tried this with DbContext API but it worked with ObjectContext API).