简体   繁体   English

C# 扩展方法类型

[英]C# extension methods types

In C#, There are two sets of extension methods (such as Where) which works on top of IEnumerable and IQueryable.在 C# 中,有两套扩展方法(例如 Where)工作在 IEnumerable 和 IQueryable 之上。 which of them used for manipulate in-memory objects and which is used for working with database.?其中哪些用于操作内存对象,哪些用于处理数据库。? Please help请帮忙

IEnumerable<T>.Where method extension.which accepts a Func<TSource, bool> predicate parameter, forcing the filtering to happen in memory. IEnumerable<T>.Where方法 extension.which 接受Func<TSource, bool> predicate参数,强制过滤发生在内存中。 While querying data from the database, IEnumerable executes select query on the server-side, loads data in-memory on the client-side and then filters the data.在从数据库查询数据时, IEnumerable在服务器端执行select query ,在客户端加载内存中的数据,然后过滤数据。 For the IEnumerable<T> case, it will be LINQ-to-object , meaning that all objects matching the original query will have to be loaded into memory from the database.对于IEnumerable<T>情况,它将是LINQ-to-object ,这意味着所有与原始查询匹配的对象都必须从数据库加载到内存中。 IEnumerable is suitable for querying data from in-memory collections like List, Array and so on. IEnumerable适用于从内存集合(如 List、Array 等)中查询数据。

IQueryable<T>.Where method extension, which accepts a Expression<Func<TSource, bool>> predicate parameter. IQueryable<T>.Where方法扩展,它接受Expression<Func<TSource, bool>> predicate参数。 Notice that this is an expression, not a delegate, which allows it to translate the where condition to a database condition.请注意,这是一个表达式,而不是一个委托,它允许将 where 条件转换为数据库条件。
While querying data from a database, IQueryable executes a select query on server-side with all filters.从数据库查询数据时, IQueryable在服务器端使用所有过滤器执行select query The difference is that IQueryable<T> is the interface that allows LINQ-to-SQL (LINQ.-to-anything really) to work.不同之处在于IQueryable<T>是允许 LINQ-to-SQL(实际上是 LINQ.-to-anything)工作的接口。 So if you further refine your query on an IQueryable<T> , that query will be executed in the database, if possible.因此,如果您进一步优化对IQueryable<T>查询,则该查询将在可能的情况下在数据库中执行。 IQueryable is suitable for querying data from out-memory (like remote database, service) collections. IQueryable适用于从内存外(如远程数据库、服务)集合中查询数据。

IEnumerable<T> exposes the enumerator, which supports a simple iteration over a collection of a specified type. IEnumerable<T>公开枚举器,它支持对指定类型的集合进行简单迭代。 so it's for in-memory objects所以它用于内存中的对象

IQueryable<T> provides functionality to evaluate queries against a specific data source wherein the type of data is known. IQueryable<T>提供了评估针对特定数据源的查询的功能,其中数据类型是已知的。 so it's for working with database所以它用于处理数据库

The answer of Reza Jenabi says the most important part. Reza Jenabi 的回答说的是最重要的部分。

I just want to add that sometimes it's very similar in code and the error may take some time to notice.我只想补充一点,有时代码非常相似,错误可能需要一些时间才能注意到。 If you write a method like :如果你写一个方法,如:

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

You're "filter" won't be translated to SQL.你的“过滤器”不会被翻译成 SQL。 All the content of the Things table will be loaded in memory, then only the filter on loaded data will apply. Things 表的所有内容都将加载到内存中,然后只应用加载数据的过滤器。 Not noticeable on an almost empty table, but awfully costly on a table with thousands of records.在几乎空的桌子上不明显,但在有数千条记录的桌子上成本非常高。

So take care to always use Expression<Func> when you want it to be executed on SQL server side :因此,当您希望在 SQL 服务器端执行它时,请注意始终使用Expression<Func>

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

Knowing that both methods will be called exactly the same way, for example :知道这两种方法将以完全相同的方式调用,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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