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