[英]C# extension methods types
在 C# 中,有两套扩展方法(例如 Where)工作在 IEnumerable 和 IQueryable 之上。 其中哪些用于操作内存对象,哪些用于处理数据库。? 请帮忙
IEnumerable<T>.Where
方法 extension.which 接受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
适用于从内存外(如远程数据库、服务)集合中查询数据。
IEnumerable<T>
公开枚举器,它支持对指定类型的集合进行简单迭代。 所以它用于内存中的对象
IQueryable<T>
提供了评估针对特定数据源的查询的功能,其中数据类型是已知的。 所以它用于处理数据库
Reza Jenabi 的回答说的是最重要的部分。
我只想补充一点,有时代码非常相似,错误可能需要一些时间才能注意到。 如果你写一个方法,如:
public List<Thing> GetList(Func<Thing, bool> filter)
{
return dbContext.Things.Where(filter).ToList();
}
你的“过滤器”不会被翻译成 SQL。 Things 表的所有内容都将加载到内存中,然后只应用加载数据的过滤器。 在几乎空的桌子上不明显,但在有数千条记录的桌子上成本非常高。
因此,当您希望在 SQL 服务器端执行它时,请注意始终使用Expression<Func>
:
public List<Thing> GetList(Expression<Func<Thing, bool>> filter)
{
return dbContext.Things.Where(filter).ToList();
}
知道这两种方法将以完全相同的方式调用,例如:
Repository.GetList(t => t.IsMyThing || t.WhateverYouWant);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.