EF相关对象过滤性能,不能用作IQueryable?

时间:2013-12-04 16:18:02

标签: c# entity-framework iqueryable

我和EF一起工作了一段时间,虽然我发现它很棒,但有些东西让我心烦意乱。

假设我说的是经典的Order / OrderDetails关系。生成的DbContext和一切。在其他属性中,我在类Order中有一个导航属性ICollection OrderDetails。

现在,为什么没有干净的方法将该导航属性用作IQueryable属性?这样,我可以在SQL端运行WHERE,以良好的性能做出类似的东西:

var argDetails = order.OrderDetails.Where(d => d.Active==true);

甚至......

order.OrderDetails.Count();

相反,它使用EntityToObjects将所有相关的详细信息提取到内存和过滤器/计数...

完全没有表现。

这背后有什么好理由吗?

由于

3 个答案:

答案 0 :(得分:1)

IQueryable是数据库查询的抽象,但IQueryable提供的功能依赖于提供程序,这使得它成为漏洞抽象。许多人主张IQueryable不应离开数据层:Using the repository pattern to support multiple providers

大多数开发人员都在努力保持POCO不受依赖关系的影响。外键和虚拟方法是大多数人会忍受的妥协,但IQueryable可能是一个太过分的步骤。

您可以在此处投票选择已过滤的内容:Allow filtering for Include extension method

参考文献:

Foreign key properties in domain entities

答案 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]