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

时间:2012-05-09 06:34:16

标签: c# .net linq list asqueryable

示例代码:

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);
}

但是如果我将查询更改为

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

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

3 个答案:

答案 0 :(得分:8)

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

对于内存集合,它是没用的。

AsQueryable用于构造表达式树时。

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

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

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

将从IQueryAble接口(查询表达式)调用studentList上的任何进一步操作,并且将仅从数据源获取那些记录,这些记录应作为最终查询结果返回(只要数据源,返回值{{ 1}}在示例中,支持QueryProvider)。

答案 1 :(得分:2)

它必须如何构建表达式树。看看这个:

  

AsQueryable是一种允许将查询转换为的方法   IQueryable的一个例子。当你使用AsQueryable运算符时   现有查询并应用进一步的转换,例如应用a   过滤或指定排序顺序,这些lambda语句是   转换为表达式树。取决于您的提供者   使用时,表达式树将被转换为特定的域   语法和执行。在Linq to SQL提供者的情况下   表达式树将转换为SQL并在SQL Server上执行。   但是,如果您在不查询的情况下使用AsQueryable运算符   实现IQueryable并且只实现IEnumerable,而不是任何   您在查询上应用的转换将自动下降   回到IEnumerable规范。这意味着通过标记a   使用AsQueryable进行查询可以获得Linq to SQL和Linq的好处   对象实现。如果您的现有查询恰好实现   IQueryable,Linq to SQL提供程序将查询转换为SQL,   否则查询将以IL代码的形式在内存中执行。

参考here

答案 2 :(得分:2)

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

某些方法需要IQueryable<T>参数。我认为AsQueryable()扩展方法对于这些方案非常有用,当您需要传递IQueryable<T>但只有IEnumerable<T>时。

MSDN说AsQueryable

  

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

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