繁体   English   中英

C# 扩展方法类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM