VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 网站开发 > ASP.net 4.0教程 >
  • asp.net教程之IQueryProvider和IQueryable<T>接口

 IQueryProvider和IQueryable<T>接口

IQueryable和IQueryable<T>同样是LINQ中非常重要的接口,在LINQ查询语句中,IQueryable和IQueryable<T>接口为LINQ查询语句进行解释和翻译工作,开发人员能够通过重写IQueryable和IQueryable<T>接口以实现用不同的方法进行不同的LINQ查询语句的解释。
IQueryable<T>继承于IEnumerable<T>和IQueryable接口,在IQueryable中包括两个重要的属性,这两个属性分别为Expression和Provider。Expression和Provider分别表示获取与IQueryable 的实例关联的表达式目录树和获取与数据源关联的查询提供程序,Provider作为其查询的翻译程序实现LINQ查询语句的解释。通过IQueryable和IQueryable<T>接口,开发人员能够自定义LINQ Provider。
注意:Provider可以被看做是一个提供者,用于提供LINQ中某个语句的解释工具,在LINQ中通过编程的方法能够实现自定义Provider。
在IQueryable和IQueryable<T>接口中,还需要另外一个接口,这个接口就是IQueryProvider,该接口用于分解表达式,实现LINQ查询语句的解释工作,这个接口也是整个算法的核心。IQueryable<T>接口在MSDN中的定义如下所示。
public interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable
{
}
public interface IQueryable : IEnumerable
{
  Type ElementType { get; }                                                                                                   //获取元素类型
  Expression Expression { get; }                                                                                           //获取表达式
  IQueryProvider Provider { get; }                                                                                         //获取提供者
}
上述代码定义了IQueryable<T>接口的规范,用于保持数据源和查询状态,IQueryProvider在MSDN中定义如下所示。
public interface IQueryProvider
{
  IQueryable CreateQuery(Expression expression);                                                                 //创建可执行对象
  IQueryable<TElement> CreateQuery<TElement>(Expression expression);           //创建可执行对象
  object Execute(Expression expression);                                                                                   //计算表达式
  TResult Execute<TResult>(Expression expression);                                                     //计算表达式
}
IQueryProvider用于LINQ查询语句的核心算法的实现,包括分解表达式和表达式计算等。为了能够创建自定义LINQ Provider,可以编写接口的实现。示例代码如下所示。
        public IQueryable<TElement> CreateQuery<TElement>(Expression expression)      
        {
            query.expression = expression;                                                                     //声明表达式
            return (IQueryable<TElement>)query;                                                         //返回query对象
        }
上述代码用于构造一个可用来执行表达式计算的IQueryable 对象,在接口中可以看到需要实现两个相同的执行表达式的IQueryable 对象,另一个则是执行表达式对象的集合,其实现代码如下所示。
        public IQueryable CreateQuery(Expression expression)
        {
            return CreateQuery<T>(expression);                                                            //返回表达式的集合
        }
而作为表达式解释和翻译的核心接口,则需要通过算法实现相应Execute方法,示例代码如下所示。
        public TResult Execute<TResult>(Expression expression)
        {
            var exp = expression as MethodCallExpression;                                       //创建表达式对象
            var data = ((exp.Arguments[0] as ConstantExpression).Value as MyQuery<T>).Data;
            var func = (exp.Arguments[1] as UnaryExpression).Operand as Expression
            <System.Func<T, bool>>;
            var lambda = Expression.Lambda<Func<T, bool>>(func.Body, func.Parameters[0]);
            var r = data.Where(lambda.Compile());                                                                //编译表达式
            return (TResult)r.GetEnumerator();
        }
上述代码通过使用lambda表达式进行表达式的计算,实现了LINQ中查询的解释功能。在LINQ中,对于表达式的翻译和执行过程都是通过IQueryProvider和IQueryable<T>接口来实现的。IQueryProvider和IQueryable<T>实现用户表达式的翻译和解释,在LINQ应用程序中,通常无需通过IQueryProvider和IQueryable<T>实现自定义LINQ Provider,因为LINQ已经提供强大表达式查询和计算功能。了解IQueryProvider和IQueryable<T>接口有助于了解LINQ内部是如何执行的。

相关教程