17

示例代码:

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;

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

4

3 回答 3

10

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

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

AsQueryable在要构建表达式树时使用。

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

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

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

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

于 2012-05-09T06:42:31.547 回答
3

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

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

MSDN 说AsQueryable

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

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

于 2012-05-09T06:51:16.250 回答
2

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

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 代码形式在内存中执行。

参考这里

于 2012-05-09T06:39:26.723 回答