【问题标题】:LINQ to Entities - Entity FrameworkLINQ to Entity - 实体框架
【发布时间】:2013-07-29 00:40:17
【问题描述】:

我希望更好地了解我们应该在何时使用 IEnumerable 而不是 IQueryablewith LINQ to Entities。

对于数据库的基本调用,IQueryable 更快,但我什么时候需要考虑使用IEnumerable 代替它?

IEnumerable 优于 IQueryable 的地方在哪里??

【问题讨论】:

    标签: c# linq-to-entities entity-framework-5


    【解决方案1】:

    基本上,IQueryables 由查询提供程序(例如数据库)执行,并且某些操作不能或不应该由数据库完成。例如,如果您想使用从数据库中获取的值调用 C# 函数(这里作为示例,名称正确大写),您可以尝试类似的操作;

    db.Users.Select(x => Capitalize(x.Name)) // Tries to make the db call Capitalize.
            .ToList();
    

    由于Select 是在IQueryable 上执行的,并且底层数据库不知道您的Capitalize 函数,因此查询将失败。相反,您可以做的是从数据库中获取正确的数据并将 IQueryable 转换为 IEnumerable (这基本上只是一种遍历内存中集合的方法)以在本地内存中执行其余操作,如下所示;

    db.Users.Select(x => x.Name)             // Gets only the name from the database
            .AsEnumerable()                  // Do the rest of the operations in memory
            .Select(x => Capitalize(x))      // Capitalize in memory
            .ToList();
    

    从 EF 的角度来看,对于 IQueryable 与 IEnumerable 的性能,最重要的是您应该始终尝试使用 IQueryable 过滤数据以获取尽可能少的数据转换为 IEnumerable。 AsEnumerable 调用基本上是告诉数据库“给我现在过滤的数据”,如果你没有过滤它,你会把所有的东西都提取到内存中,甚至是你可能不需要的数据。

    【讨论】:

      【解决方案2】:

      IEnumerable 表示一系列元素,您可以逐个枚举,直到找到所需的答案,例如,如果我想要所有属性大于 10 的实体,我需要遍历每个元素反过来,只返回那些匹配的。将数据库表的每一行都拉入内存以执行此操作可能不是一个好主意。

      另一方面,IQueryable 表示一组元素,在这些元素上,过滤等操作可以推迟到底层数据源,所以在过滤的情况下,如果我要在自定义数据源之上实现 IQueryable (或使用 LINQ to Entities!)然后我可以将过滤/分组等的艰苦工作交给数据源(例如数据库)。

      IQueryable 的主要缺点是实现它非常困难 - 查询被构造为表达式树,作为实现者,您必须解析这些树才能解析查询。如果您不打算编写提供程序,那么这不会伤害您。

      值得了解的 IQueryable 的另一个方面(尽管这实际上只是一个通用警告,将处理传递给可能对世界做出不同假设的另一个系统)是您可能会在源系统支持它们的方式,而不是消费者实现它们的方式,例如如果您的源数据库不区分大小写,但 .NET 中的默认比较区分大小写。

      【讨论】:

        猜你喜欢
        • 2011-04-27
        • 1970-01-01
        • 1970-01-01
        • 2017-08-15
        • 2010-09-05
        • 1970-01-01
        • 2011-01-15
        • 1970-01-01
        • 2011-11-02
        相关资源
        最近更新 更多