IQueryable在LINQ中

  1 IQueryable接口定义如下: 
  2     // 摘要:
  3     //     提供对未指定数据类型的特定数据源的查询进行计算的功能。
  4     public interface IQueryable : IEnumerable
  5     {
  6         // 摘要:
  7         //     获取在执行与 System.Linq.IQueryable 的此实例关联的表达式目录树时返回的元素的类型。
  8         //
  9         // 返回结果:
 10         //     一个 System.Type,表示在执行与之关联的表达式目录树时返回的元素的类型。
 11         Type ElementType { get; }
 12         //
 13         // 摘要:
 14         //     获取与 System.Linq.IQueryable 的实例关联的表达式目录树。
 15         //
 16         // 返回结果:
 17         //     与 System.Linq.IQueryable 的此实例关联的 System.Linq.Expressions.Expression。
 18         Expression Expression { get; }
 19         //
 20         // 摘要:
 21         //     获取与此数据源关联的查询提供程序。
 22         //
 23         // 返回结果:
 24         //     与此数据源关联的 System.Linq.IQueryProvider。
 25         IQueryProvider Provider { get; }
 26     }
 27 IQueryProvider接口定义如下:
 28     // 摘要:
 29     //     定义用于创建和执行 System.Linq.IQueryable 对象所描述的查询的方法。
 30     public interface IQueryProvider
 31     {
 32         // 摘要:
 33         //     构造一个 System.Linq.IQueryable 对象,该对象可计算指定表达式目录树所表示的查询。
 34         //
 35         // 参数:
 36         //   expression:
 37         //     表示 LINQ 查询的表达式目录树。
 38         //
 39         // 返回结果:
 40         //     一个 System.Linq.IQueryable,它可计算指定表达式目录树所表示的查询。
 41         IQueryable CreateQuery(Expression expression);
 42         //
 43         // 摘要:
 44         //     构造一个 System.Linq.IQueryable<T> 对象,该对象可计算指定表达式目录树所表示的查询。
 45         //
 46         // 参数:
 47         //   expression:
 48         //     表示 LINQ 查询的表达式目录树。
 49         //
 50         // 类型参数:
 51         //   TElement:
 52         //     返回的 System.Linq.IQueryable<T> 的元素的类型。
 53         //
 54         // 返回结果:
 55         //     一个 System.Linq.IQueryable<T>,它可计算指定表达式目录树所表示的查询。
 56         IQueryable<TElement> CreateQuery<TElement>(Expression expression);
 57         //
 58         // 摘要:
 59         //     执行指定表达式目录树所表示的查询。
 60         //
 61         // 参数:
 62         //   expression:
 63         //     表示 LINQ 查询的表达式目录树。
 64         //
 65         // 返回结果:
 66         //     执行指定查询所生成的值。
 67         object Execute(Expression expression);
 68         //
 69         // 摘要:
 70         //     执行指定表达式目录树所表示的强类型查询。
 71         //
 72         // 参数:
 73         //   expression:
 74         //     表示 LINQ 查询的表达式目录树。
 75         //
 76         // 类型参数:
 77         //   TResult:
 78         //     执行查询所生成的值的类型。
 79         //
 80         // 返回结果:
 81         //     执行指定查询所生成的值。
 82         TResult Execute<TResult>(Expression expression);
 83     }
 84 
 85 
 86 通过这种接口设计,IQueryable允许开发人员创建支持其他非SQL Server数据库的实现。
 87 Provider将借助于IQueryable所提供的种种信息把查询语句转换为另一种形式,转换的实际操作将由CreateQuery方法实现,随后转换的结果将由Execute方法使用。
 88 为了理解IQueryable,我们看如下查询:
 89 IEnumerable<Book> query = DataContext.Books.Where(book => book.Price > 30); 
 90 
 91 若DataContext.Books对象仅实现了IEnumerable<T>,那么编译器会把该查询直接翻译成一系列标准的静态方法调用:
 92                 IEnumerable<Book> query =
 93                     System.Linq.Enumerable.Where<Book>(
 94                     delegate(Book book) { return book.Price > 30.0M; });
 95 
 96 若是DataContext.Books对象还实现了IQueryable<T>,那么编译器将把查询转换成一棵表达式树:
 97                 LinqBooksDataContext context = new LinqBooksDataContext(); 
 98 
 99                 var bookParam = Expression.Parameter(typeof(Book), "book");
100 
101                 var query = context.Books.Where<Book>(Expression.Lambda<Func<Book, bool>>(
102                     Expression.GreaterThan(
103                     Expression.Property(
104                     bookParam,
105                     typeof(Book).GetProperty("Price")),
106                     Expression.Constant(30M, typeof(decimal?))),
107                     new ParameterExpression[] { bookParam })); 
108 
109 IQueryable的Provider即可将这个结构转换为能够被底层数据源所理解的查询语句。
posted @ 2017-06-12 13:59  herizai  阅读(521)  评论(0编辑  收藏  举报