[英]EF Related Objects Filter Performance, can't use as IQueryable?
我与EF合作已有一段时间了,虽然我发现它很棒,但是有些事情困扰着我。
假设我说的是经典的Order / OrderDetails关系。 DbContext生成了所有内容。 在其他属性中,我在类Order中具有导航属性ICollection OrderDetails。
现在,为什么没有干净的方法将该导航属性用作IQueryable属性? 这样,我就可以在SQL端运行WHERE从而获得良好的性能:
var argDetails = order.OrderDetails.Where(d => d.Active==true);
甚至...
order.OrderDetails.Count();
取而代之的是,这会使用EntityToObjects将所有相关的详细信息提取到内存中并进行过滤/计数。
完全没有表现。
这背后有什么充分的理由吗?
谢谢
IQueryable
是数据库查询的抽象,但是IQueryable
提供的功能取决于提供程序,这使其成为泄漏的抽象。 许多人主张IQueryable
不应走出数据层: 使用存储库模式来支持多个提供程序
大多数开发人员都在努力使POCO不受依赖的影响。 外键和虚拟方法是大多数人都无法接受的折衷方案,但IQueryable
可能离此步骤还很远。
您可以在此处对过滤的包含进行投票: 允许对包含扩展方法进行过滤
参考文献:
希望我不会误会您的问题,但是您是否正在寻找ObjectContext.LoadProperty
另外: 如何:显式加载POCO实体
context.LoadProperty(order, "OrderDetails");
你是对的,关键是要获取一个IQueryable
例如:
Int32 i = ctx.Orders.Where(x => x.Id == 1).SelectMany(x => x.Details).Where(y => y.IsActive).Select(x => 1).Sum();
运行服务器端
因此,对您的问题的回答可能是:因为可以通过其他方式完成,而以这种方式进行操作则可以实现其他方式无法实现的事情。 :)
请不要问我还有什么其他事情:)。
编辑
Int32 i = ctx.Orders.Where(x => x.Id == 1).SelectMany(x => x.Details).Where(y => y.IsActive).Count();
与几乎相同的查询等效:
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
SUM(1) AS [A1]
FROM [dbo].[OrderDetails] AS [Extent1]
WHERE (1 = [Extent1].[Order_Id]) AND ([Extent1].[IsActive] = 1)
) AS [GroupBy1]
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[OrderDetails] AS [Extent1]
WHERE (1 = [Extent1].[Order_Id]) AND ([Extent1].[IsActive] = 1)
) AS [GroupBy1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.