C# 我真的需要在集合上使用 AsQueryable() 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10510890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 14:08:16  来源:igfitidea点击:

Do i really need use AsQueryable() on collection?

c#.netlinqlistasqueryable

提问by Cheung

Example code:

示例代码:

List<Student> Students = new List<Student>()   
{   
    new Student(101, "Hugo", "Garcia", new List<int>() { 91, 88, 76, 93 }),  
    new Student(102, "Rick", "Adams", new List<int>() { 70, 73, 66, 90 }),  
    new Student(103, "Michael", "Tucker", new List<int>() { 73, 80, 75, 88 }),  
    new Student(104, "Fadi", "Fakhouri", new List<int>() { 82, 75, 66, 84 }),  
    new Student(105, "Peter", "Barrows", new List<int>() { 67, 78, 70, 82 })  
};

var query = from student in Students
            where student.Marks.AsQueryable().All(m => m > 70)
            select student;

foreach (Student student in query)
{
    Console.WriteLine("{0} {1}<br />", student.FirstName, student.LastName);
}

But if I change the query to

但是如果我将查询更改为

var query = from student in Students
            where student.Marks.All(m => m > 70)
            select student;

This also works and produces the same result, so what's the difference?

这也有效并产生相同的结果,那么有什么区别呢?

采纳答案by Tilak

IQueryable is required/recommended for objects coming from remote source (like from database).

对于来自远程源(如来自数据库)的对象,需要/推荐使用 IQueryable。

For in memory collections it is of no use.

因为在内存集合中它是没有用的。

AsQueryableis used when expression tree is to be constructed.

当要构建表达式树时使用AsQueryable

I can think of scenario where it is best fit. In your example let say you require some information from database based on student ID.

我可以想到最适合的场景。在您的示例中,假设您需要基于学生 ID 的数据库中的一些信息。

Now student is in memory collection. You need to fire database query based on student ID.

现在学生在记忆收集中。您需要根据学生 ID 触发数据库查询。

  var studentList = Students.Select(s => s.Id).AsQueryAble().Select(i => remoteDBProvider.GetInfo(i));

Any further operation on the studentList will be invoked from IQueryAble interface ( query expression), and will fetch only those records from data source, which should be returned as final query result (as long as data source, return value of remoteDBProvider.GetInfoin the example, supports QueryProvider).

对 studentList 的任何进一步操作都会从 IQueryAble 接口(查询表达式)调用,并且只会从数据源中获取那些应该作为最终查询结果返回的记录(只要数据源,返回值remoteDBProvider.GetInfo在示例中,支持查询提供者)。

回答by Arion

It has to do how the expression tree is build. Look at this:

它必须做表达式树的构建方式。看这个:

AsQueryable is a method that allow the query to be converted to an instance of IQueryable. When you use AsQueryable operator on an existing query and apply further transformations such as applying a filter or specifying a sort order, those lambda statements are converted to Expression trees. Depending on the provider you are using, expression trees will be converted into the domain specific syntax and than executed. In the case of Linq to SQL provider, the expression tree would be converted to SQL and executed on SQL server. However if you use AsQueryable operator on a query that does not implement IQueryable and only implements IEnumerable, than any transformations that you apply on the query would automatically fall back on IEnumerable specification. What this means is by tagging a query with AsQueryable you get benefits of both Linq to SQL and Linq to object implementation. If your existing query happens to implement IQueryable, the query is converted to SQL by the Linq to SQL provider, otherwise the query is executed in memory in the form IL code.

AsQueryable 是一种允许将查询转换为 IQueryable 实例的方法。当您对现有查询使用 AsQueryable 运算符并应用进一步的转换(例如应用过滤器或指定排序顺序)时,这些 lambda 语句将转换为表达式树。根据您使用的提供程序,表达式树将转换为特定于域的语法并执行。在 Linq to SQL 提供程序的情况下,表达式树将转换为 SQL 并在 SQL 服务器上执行。但是,如果您在未实现 IQueryable 且仅实现 IEnumerable 的查询上使用 AsQueryable 运算符,则您对查询应用的任何转换都将自动回退到 IEnumerable 规范。这意味着通过使用 AsQueryable 标记查询,您可以获得 Linq to SQL 和 Linq to object 实现的好处。如果您现有的查询恰好实现了 IQueryable,则该查询会被 Linq to SQL 提供程序转换为 SQL,否则该查询将以 IL 代码的形式在内存中执行。

Reference here

参考这里

回答by Botz3000

In the case of your List<Student>, it doesn't make any difference, as the returned IQueryable<T>will use the same methods for querying as if you hadn't used AsQueryable()at all.

对于您的List<Student>,它没有任何区别,因为返回的IQueryable<T>将使用相同的方法进行查询,就好像您根本没有使用AsQueryable()过一样。

Some Methods expect an IQueryable<T>parameter. I think the AsQueryable()extension method is mostly useful for those scenarios, when you need to pass an IQueryable<T>but only have an IEnumerable<T>.

有些方法需要一个IQueryable<T>参数。我认为AsQueryable()扩展方法对于那些场景最有用,当你需要传递一个IQueryable<T>但只有一个IEnumerable<T>.

MSDN says about AsQueryable:

MSDN 说AsQueryable

If the type of source implements IQueryable<T>, AsQueryable<TElement>(IEnumerable<TElement>)returns it directly. Otherwise, it returns an IQueryable<T>that executes queries by calling the equivalent query operator methods in Enumerableinstead of those in Queryable.

如果 source 的类型实现IQueryable<T>AsQueryable<TElement>(IEnumerable<TElement>)则直接返回。否则,它返回IQueryable<T>通过调用等效的查询运算符方法 inEnumerable而不是 中的方法来执行查询的Queryable

So that means in your case (List<T>does not implement IQueryable<T>), you really don't need AsQueryable.

所以这意味着在你的情况下(List<T>没有实现IQueryable<T>),你真的不需要AsQueryable.