【问题标题】:C# extension methods typesC# 扩展方法类型
【发布时间】:2020-04-15 22:56:00
【问题描述】:

在 C# 中,有两组扩展方法(例如 Where)在 IEnumerable 和 IQueryable 之上工作。其中哪些用于操作内存中的对象,哪些用于处理数据库。?请帮忙

【问题讨论】:

  • IEnumerableIQueryable 都可以与任何类型的集合一起使用,无论是在内存中还是在内存中。但在实践中,IQueryable 更常用于数据库,因为它具有更好的机制来处理外部数据源。

标签: c# .net extension-methods ienumerable iqueryable


【解决方案1】:

IEnumerable<T> 公开了枚举器,它支持对指定类型的集合进行简单迭代。所以它适用于内存中的对象

IQueryable<T> 提供了针对数据类型已知的特定数据源评估查询的功能。所以它是用来处理数据库的

【讨论】:

  • @Hans Kesting:是的,在 LINQ 扩展方法中使用了泛型类型,所以我更新了我的答案
【解决方案2】:

IEnumerable<T>.Where 方法扩展。它接受Func<TSource, bool> predicate 参数, 强制过滤发生在内存中。 在从数据库中查询数据时,IEnumerable 在服务器端执行select query, 在客户端加载内存中的数据,然后过滤数据。 对于IEnumerable<T> 的情况,它将是LINQ-to-object,这意味着与原始查询匹配的所有对象都必须从数据库加载到内存中。 IEnumerable 适用于查询List、Array等内存集合中的数据。

IQueryable<T>.Where 方法扩展,它接受Expression<Func<TSource, bool>> predicate 参数。 请注意,这是一个表达式,而不是一个委托,它允许它将 where 条件转换为 数据库条件。
在从数据库查询数据时,IQueryable 在服务器端使用所有过滤器执行select query。 不同之处在于IQueryable<T> 是允许LINQ-to-SQL(LINQ.-to-anything)工作的接口。 因此,如果您在IQueryable<T> 上进一步细化您的查询,如果可能,该查询将在数据库中执行。 IQueryable 适用于从内存外(如远程数据库、服务)集合中查询数据。

【讨论】:

    【解决方案3】:

    Reza Jenabi 的回答说明了最重要的部分。

    我只是想补充一点,有时它的代码非常相似,错误可能需要一些时间才能注意到。如果你写这样的方法:

    public List<Thing> GetList(Func<Thing, bool> filter)
    {
        return dbContext.Things.Where(filter).ToList();
    }
    

    您的“过滤器”不会被翻译成 SQL。 Things 表的所有内容都将加载到内存中,然后仅应用加载数据的过滤器。 在几乎空的表上不明显,但在有数千条记录的表上成本非常高。

    因此,当您希望在 SQL 服务器端执行 Expression&lt;Func&gt; 时,请注意始终使用它:

    public List<Thing> GetList(Expression<Func<Thing, bool>> filter)
    {
        return dbContext.Things.Where(filter).ToList();
    }
    

    知道两种方法的调用方式完全相同,例如:

    Repository.GetList(t => t.IsMyThing || t.WhateverYouWant);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多