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即可将这个结构转换为能够被底层数据源所理解的查询语句。