LINQ学习笔记:表达式树_SQL SERVER数据库_黑客防线网安服务器维护基地--Powered by WWW.RONGSEN.COM.CN

LINQ学习笔记:表达式树

作者:黑客防线网安SQL维护基地 来源:黑客防线网安SQL维护基地 浏览次数:0

本篇关键词:笔记学习表达式
黑客防线网安网讯:      构建查询表达式本节中, 我们假设我们拥有一个这样的实体类:   1: [Table] public partial class Product   2:     3: {   4:     5:   [Column(IsPrimaryKey=true)] public int ID;  ...

      构建查询表达式

本节中, 我们假设我们拥有一个这样的实体类:

   1: [Table] public partial class Product   2:     3: {   4:     5:   [Column(IsPrimaryKey=true)] public int ID;   6:     7:   [Column]                    public string Description;   8:     9:   [Column]                    public bool Discontinued;  10:    11:   [Column]                    public DateTime LastSale;  12:    13: }

委托 VS 表达式树

让我们回忆一下:

1. 本地查询,使用的Enumerable操作符,使用委托

2. 解释查询(Interpreted Query),使用Queryable操作符,使用表达式树

我们可以比较一下Where操作符在Enumerable和Queryable当中的签名:

   1: public static IEnumerable Where (this   2:     3:   IEnumerable source,   4:     5:   Funcbool> predicate)   6:     7: public static IQueryable Where (this   8:     9:   IQueryable source,  10:    11:   Expressionbool>> predicate)

当把他们嵌入到一个查询当中的时候,Lamdba表达式看上去都是一样的无论它是绑定到Enumerable或者Queryable:

   1: IEnumerable q1 = localProducts.Where   2:     3:                                (p => !p.Discontinued);   4:     5: IQueryable q2 = sqlProducts.Where   6:     7:                               (p => !p.Discontinued);

当你将一个Lambda表达式赋给一个中间变量的时候, 你必须显示地指示是将它绑定到委托(Func<>)或者是表达式树(Expression<>>)

编译表达式树

通过调用Compile我们可以将一个表达式树转换为委托. 当我们编写的方法返回可重用的表达式时这回带来特别的价值. 为了演示,我们将给Product类增加一个静态方法, 其返回一个bool值用于断言那些Discontinued并且在过去30天内销售的产品.

   1: public partial class Product   2:     3: {   4:     5:   public static Expressionbool>>   6:     7:   IsSelling()   8:     9:   {  10:    11:     return p => !p.Discontinued &&  12:    13:                 p.LastSale > DateTime.Now.AddDays (-30);  14:    15:   }  16:    17: }

(注:对于类似的扩展方法,我们应该编写一个全新的文件从而避免去覆盖由VS的设计器自动产生的文件.)

此方法可以同时被用于本地查询和解释查询,如下所示:

   1: void Test( )   2:     3: {   4:     5:   var dataContext = new MyTypedDataContext (“connectionString”);   6:     7:   Product[] localProducts =   8:     9:     dataContext.Products.ToArray( );  10:    11:   IQueryable sqlQuery =  12:    13:     dataContext.Products.Where(Product.IsSelling());  14:    15:   IEnumerable localQuery =  16:    17:     localProducts.Where(Product.IsSelling.Compile());  18:    19: }

相比之下, 我们并不能将一个委托转换为表达式树,这也使得表达式树更加有用.

AsQueryable

使用AsQueryable操作符可以编写用于操作本地或者远程序列的查询:

   1: IQueryable FilterSortProducts   2:     3:   (IQueryable input)   4:     5: {   6:     7:    return from p in input   8:     9:           where …  10:    11:           order by …  12:    13:           select p;  14:    15: }  16:    17: void Test()  18:    19: {  20:    21:   var dataContext = new MyTypedDataContext (“connectionString”);  22:    23:   Product[]localProducts =  24:    25:     dataContext.Products.ToArray();  26:    27:   var sqlQuery =  28:    29:     FilterSortProducts (dataContext.Products);  30:    31:   var localQuery =  32:    33:     FilterSortProducts (localProducts.AsQueryable());  34:    35: }

AsQueryable对本地查询包装了一层Queryable<>外衣,这使得接下来的子查询都是针对表达式树的.当你开始枚举结果集的时候表达式树会被隐式编译转换成为本地查询然后向往常一直执行.

表达式树

我们之前说过将一个Lambda表达式赋值给一个Expression类型变量会引起C#编译器解析表达式树.使用编程手段, 我们可以在运行时做相同的事情-换句话说, 从零开始动态创建表达式树. 结果集可以被转换为Expression并被使用于LINQ to SQL查询中,或者通过调用Compile将其转换为委托.

表达式DOM

一个表达式树是一个小型DOM. 每一个节点表示一个System.Linq.Expressions命名空间下的一个类型. 其基类是Expression(非泛型),而泛型Expression实际上是表示类型化的Lambda表达式.

Expression<>的基类是非泛型的LambdaExpression类, LambdaExpression提供了针对Labmbda表达式树的统一类型:任何Expression<>都看可以被转换为LambdaExpression.

为了创建表达式树, 我们并不需要直接实例化节点类,而是通过调用Expression类提供的静态方法:

   1: //创建输入参数s   2: ParameterExpression p = Expression.Parameter(typeof(string), “s”);   3: //参数属性Length   4: MemberExpression stringLength = Expression.Property(p, “Length”);   5: //常量5   6: ConstantExpression five = Expression.Constant(5);   7: //比较操作符   8: BinaryExpression comparison = Expression.LessThan(stringLength, five);   9: Expression<string,bool>> lambda = Expression.Lambda<string,bool>>(comparison,p);  10: //转换为委托  11: Func<string, bool> runnable = lambda.Compile();  12: Console.WriteLine(runnable(“James”)); //False  13: Console.WriteLine(runnable(“dog”)); //True

此示例动态创建了一个如下的Lambda表达式:

   1: Expression<string, bool>> f = s => s.Length < 5;

待续!

    黑客防线网安服务器维护方案本篇连接:http://www.rongsen.com.cn/show-10818-1.html
网站维护教程更新时间:2012-03-21 03:10:48  【打印此页】  【关闭
我要申请本站N点 | 黑客防线官网 |  
专业服务器维护及网站维护手工安全搭建环境,网站安全加固服务。黑客防线网安服务器维护基地招商进行中!QQ:29769479

footer  footer  footer  footer