表达式树 php,Linux_LINQ学习笔记:表达式树,构建查询表达式本节中, 我们 - phpStudy...
構(gòu)建查詢表達(dá)式
本節(jié)中, 我們假設(shè)我們擁有一個(gè)這樣的實(shí)體類:
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表達(dá)式樹(shù)
讓我們回憶一下:
1. 本地查詢,使用的Enumerable操作符,使用委托
2. 解釋查詢(Interpreted Query),使用Queryable操作符,使用表達(dá)式樹(shù)
我們可以比較一下Where操作符在Enumerable和Queryable當(dāng)中的簽名:
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)
當(dāng)把他們嵌入到一個(gè)查詢當(dāng)中的時(shí)候,Lamdba表達(dá)式看上去都是一樣的,無(wú)論它是綁定到Enumerable或者Queryable:
1: IEnumerable q1 = localProducts.Where
2:
3: (p => !p.Discontinued);
4:
5: IQueryable q2 = sqlProducts.Where
6:
7: (p => !p.Discontinued);
當(dāng)你將一個(gè)Lambda表達(dá)式賦給一個(gè)中間變量的時(shí)候, 你必須顯示地指示是將它綁定到委托(Func<>)或者是表達(dá)式樹(shù)(Expression<>>)
編譯表達(dá)式樹(shù)
通過(guò)調(diào)用Compile我們可以將一個(gè)表達(dá)式樹(shù)轉(zhuǎn)換為委托. 當(dāng)我們編寫的方法返回可重用的表達(dá)式時(shí)這回帶來(lái)特別的價(jià)值. 為了演示,我們將給Product類增加一個(gè)靜態(tài)方法, 其返回一個(gè)bool值用于斷言那些Discontinued并且在過(guò)去30天內(nèi)銷售的產(chǎn)品.
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: }
(注:對(duì)于類似的擴(kuò)展方法,我們應(yīng)該編寫一個(gè)全新的文件從而避免去覆蓋由VS的設(shè)計(jì)器自動(dòng)產(chǎn)生的文件.)
此方法可以同時(shí)被用于本地查詢和解釋查詢,如下所示:
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: }
相比之下, 我們并不能將一個(gè)委托轉(zhuǎn)換為表達(dá)式樹(shù),這也使得表達(dá)式樹(shù)更加有用.
AsQueryable
使用AsQueryable操作符可以編寫用于操作本地或者遠(yuǎn)程序列的查詢:
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對(duì)本地查詢包裝了一層Queryable<>外衣,這使得接下來(lái)的子查詢都是針對(duì)表達(dá)式樹(shù)的.當(dāng)你開(kāi)始枚舉結(jié)果集的時(shí)候,表達(dá)式樹(shù)會(huì)被隱式編譯轉(zhuǎn)換成為本地查詢?nèi)缓笙蛲R恢眻?zhí)行.
表達(dá)式樹(shù)
我們之前說(shuō)過(guò)將一個(gè)Lambda表達(dá)式賦值給一個(gè)Expression類型變量會(huì)引起C#編譯器解析表達(dá)式樹(shù).使用編程手段, 我們可以在運(yùn)行時(shí)做相同的事情-換句話說(shuō), 從零開(kāi)始動(dòng)態(tài)創(chuàng)建表達(dá)式樹(shù). 結(jié)果集可以被轉(zhuǎn)換為Expression并被使用于LINQ to SQL查詢中,或者通過(guò)調(diào)用Compile將其轉(zhuǎn)換為委托.
表達(dá)式DOM
一個(gè)表達(dá)式樹(shù)是一個(gè)小型DOM. 每一個(gè)節(jié)點(diǎn)表示一個(gè)System.Linq.Expressions命名空間下的一個(gè)類型. 其基類是Expression(非泛型),而泛型Expression實(shí)際上是表示類型化的Lambda表達(dá)式.
Expression<>的基類是非泛型的LambdaExpression類, LambdaExpression提供了針對(duì)Labmbda表達(dá)式樹(shù)的統(tǒng)一類型:任何Expression<>都看可以被轉(zhuǎn)換為L(zhǎng)ambdaExpression.
為了創(chuàng)建表達(dá)式樹(shù), 我們并不需要直接實(shí)例化節(jié)點(diǎn)類,而是通過(guò)調(diào)用Expression類提供的靜態(tài)方法:
1: //創(chuàng)建輸入?yún)?shù)s
2: ParameterExpression p = Expression.Parameter(typeof(string), “s”);
3: //參數(shù)屬性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> lambda = Expression.Lambda>(comparison,p);
10: //轉(zhuǎn)換為委托
11: Func runnable = lambda.Compile();
12: Console.WriteLine(runnable(“James”)); //False
13: Console.WriteLine(runnable(“dog”)); //True
此示例動(dòng)態(tài)創(chuàng)建了一個(gè)如下的Lambda表達(dá)式:
1: Expression> f = s => s.Length < 5;
待續(xù)!
總結(jié)
以上是生活随笔為你收集整理的表达式树 php,Linux_LINQ学习笔记:表达式树,构建查询表达式本节中, 我们 - phpStudy...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java中有ClockPane类吗,Ja
- 下一篇: linux更改用户的shell,Linu