我和EF一起工作了一段时间,虽然我发现它很棒,但有些东西让我心烦意乱。
假设我说的是经典的Order / OrderDetails关系。生成的DbContext和一切。在其他属性中,我在类Order中有一个导航属性ICollection OrderDetails。
现在,为什么没有干净的方法将该导航属性用作IQueryable属性?这样,我可以在SQL端运行WHERE,以良好的性能做出类似的东西:
var argDetails = order.OrderDetails.Where(d => d.Active==true);
甚至......
order.OrderDetails.Count();
相反,它使用EntityToObjects将所有相关的详细信息提取到内存和过滤器/计数...
完全没有表现。
这背后有什么好理由吗?
由于
答案 0 :(得分:1)
IQueryable
是数据库查询的抽象,但IQueryable
提供的功能依赖于提供程序,这使得它成为漏洞抽象。许多人主张IQueryable
不应离开数据层:Using the repository pattern to support multiple providers
大多数开发人员都在努力保持POCO不受依赖关系的影响。外键和虚拟方法是大多数人会忍受的妥协,但IQueryable
可能是一个太过分的步骤。
您可以在此处投票选择已过滤的内容:Allow filtering for Include extension method
参考文献:
答案 1 :(得分:0)
我希望我没有误解你的问题,但是你在寻找ObjectContext.LoadProperty
另外:How to: Explicitly Load POCO Entities
context.LoadProperty(order, "OrderDetails");
答案 2 :(得分:0)
你是对的,重点是获得一个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]