C#扩展方法类型

问题描述 投票:1回答:3

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

c# .net extension-methods ienumerable iqueryable
3个回答
5
投票

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

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


2
投票

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

IEnumerable<T>提供了针对已知数据类型的特定数据源评估查询的功能。因此是用于数据库


0
投票

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

我只想补充一点,有时它在代码上非常相似,并且该错误可能需要一些时间才能注意到。如果您编写类似::>的方法

IQueryable<T>

您是“过滤器”,不会转换为SQL。 Things表的所有内容都将被加载到内存中,然后仅应用已加载数据的过滤器。在几乎是空的表上并不明显,但是在具有数千条记录的表上却非常昂贵。

因此,当您希望在SQL Server端执行IQueryable<T>时请务必始终使用public List<Thing> GetList(Func<Thing, bool> filter) { return dbContext.Things.Where(filter).ToList(); } :>

Expression<Func>

知道这两种方法将完全相同地被调用,例如:

public List<Thing> GetList(Expression<Func<Thing, bool>> filter)
{
    return dbContext.Things.Where(filter).ToList();
}
© www.soinside.com 2019 - 2024. All rights reserved.