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

14 浏览
0 Comments

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

示例代码:\n

List Students = new List()   
{   
    new Student(101, "Hugo", "Garcia", new List() { 91, 88, 76, 93 }),  
    new Student(102, "Rick", "Adams", new List() { 70, 73, 66, 90 }),  
    new Student(103, "Michael", "Tucker", new List() { 73, 80, 75, 88 }),  
    new Student(104, "Fadi", "Fakhouri", new List() { 82, 75, 66, 84 }),  
    new Student(105, "Peter", "Barrows", new List() { 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}", student.FirstName, student.LastName);
}

\n但是如果我将查询更改为:\n

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

\n这也能正常工作并产生相同的结果,那么有什么区别呢?

0
0 Comments

在使用LINQ进行查询时,有时会遇到需要将一个集合转换为`IQueryable`的情况。而`AsQueryable()`方法就是用来实现这一转换的。当我们在一个已有的查询中使用`AsQueryable()`方法,并对其进行进一步的转换,比如应用筛选条件或者指定排序顺序时,这些Lambda表达式将会被转换为表达式树。根据所使用的提供程序的不同,表达式树将被转换为特定于领域的语法,然后执行。在使用Linq to SQL提供程序的情况下,表达式树将被转换为SQL并在SQL服务器上执行。然而,如果我们在一个只实现了`IEnumerable`而没有实现`IQueryable`的查询上使用`AsQueryable()`方法,那么应用在查询上的任何转换都将自动回退到`IEnumerable`规范。这意味着,通过在查询上使用`AsQueryable`方法,我们既可以享受到Linq to SQL的优势,也可以享受到Linq to Object的实现。如果我们的现有查询已经实现了`IQueryable`,那么该查询将由Linq to SQL提供程序转换为SQL,否则该查询将以IL代码的形式在内存中执行。

解决方法:对于一个已有的查询,如果我们想要在其上应用进一步的转换,同时又希望利用Linq to SQL和Linq to Object的优势,我们可以使用`AsQueryable()`方法将其转换为`IQueryable`类型的查询。这样一来,不管该查询是实现了`IQueryable`还是`IEnumerable`,我们都可以对其进行进一步的转换操作,而不会受到`IEnumerable`规范的限制。

0
0 Comments

在你的List<Student>的情况下,使用AsQueryable()并没有任何区别,因为返回的IQueryable<T>将使用与没有使用AsQueryable()时相同的查询方法。一些方法期望一个IQueryable<T>参数。我认为AsQueryable()扩展方法在那些需要传递IQueryable<T>但只有IEnumerable<T>的情况下非常有用。

MSDN关于AsQueryable的解释是:

如果源类型实现了IQueryable<T>

AsQueryable<TElement>(IEnumerable<TElement>)将直接返回它。

否则,它返回一个IQueryable<T>,该IQueryable<T>通过调用Enumerable中的等效查询操作符方法来执行查询,而不是调用Queryable中的方法。

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

0
0 Comments

Do I really need to use AsQueryable() on a collection?

有时候我们在处理集合对象时,会遇到是否需要使用AsQueryable()方法的问题。在处理来自远程源(如数据库)的对象时,使用IQueryable是必需或者推荐的。但对于内存中的集合对象来说,使用IQueryable没有任何作用。

AsQueryable()方法用于构建表达式树。在下面的例子中,我们可以想象一种最适合使用AsQueryable()的场景。假设我们需要根据学生ID从数据库中获取一些信息。现在学生信息存储在内存集合中,我们需要根据学生ID来查询数据库。

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

对studentList的任何后续操作都将通过IQueryable接口(查询表达式)进行调用,并且只会从数据源中获取那些应该作为最终查询结果返回的记录(只要数据源支持QueryProvider,例如上面例子中的remoteDBProvider.GetInfo的返回值)。这是因为Queryable接受lambda表达式作为表达式,这允许查询提供程序检查表达式并将其转换为更高效的查询形式,例如SQL查询。任何投影或过滤都将在数据库中进行,而不是在应用程序中进行,以充分利用数据库的本地代码。但对于内存集合来说,这没有任何区别。

然而,即使对于内存集合来说,AsQueryable仍然有其用途,因为它的Select扩展方法接受一个Expression,这使您能够分析或修改它。我能想到的一个场景是,将内存集合包装在一个IQueryable中,作为一个无持久化意识的层向一个持久化意识的层发送一个查询作为AST(抽象语法树)的方式。

,对于来自远程源的对象来说,使用IQueryable是必需或者推荐的。但对于内存中的集合对象来说,使用IQueryable并没有太大意义。然而,即使对于内存集合来说,AsQueryable仍然有其用途,因为它允许我们使用表达式树来分析或修改查询。

0