我先拋出一些問題
要從sqlserver數(shù)據(jù)庫某張表中查找某個(gè)叫 zhangsan的人的信息怎么找?很簡單 sql語句: select * from _yourTable where name='zhangsan'現(xiàn)在同樣的數(shù)據(jù)存放在xml文件里,我也要找到叫張三的怎么辦?(不使用linq to xml)也不復(fù)雜,使用xml 的XPath也可以找出來。現(xiàn)在這些數(shù)據(jù)存放在其他類型的數(shù)據(jù)庫中咋辦? o(╯□╰)o 繼續(xù)寫可能不一樣的sql語句.....................這樣子針對同樣的數(shù)據(jù)存放在不同介質(zhì)中(內(nèi)存,xml, 遠(yuǎn)程數(shù)據(jù)庫 )有沒有可能設(shè)計(jì)一種 數(shù)據(jù)結(jié)構(gòu)能簡明的表達(dá)這種意思,然后針對不同的存儲(chǔ)介質(zhì)在解析成對應(yīng)的處理方式呢?只要能解析成下面這樣子的二叉樹數(shù)據(jù)結(jié)構(gòu)就可以了。
要表達(dá)這樣的意思,就要用到今天的主角了 lambda 表達(dá)式樹。lambda 如果用作委托的參數(shù),那他就會(huì)在底層被編譯為一個(gè)匿名函數(shù),而如果傳給C# ExPRession那就成了一個(gè)表達(dá)式樹了,相當(dāng)于是存儲(chǔ)的描述數(shù)據(jù)結(jié)構(gòu)的信息,這個(gè)信息可以被分析然后處理。如下Expression<Func<string,bool>> filter=name=>name=="zhangsan";現(xiàn)在 filter和委托對象就不一樣了,它并不是可執(zhí)行代碼,如果直接filter()編譯會(huì)出錯(cuò),如果現(xiàn)在又要想從個(gè)表達(dá)式樹信息變成可執(zhí)行代碼怎么辦?如下 Expression< Func<string , bool >> filter = x => x == "zhangsan" ; var compile = filter.Compile(); bool iszhangsan = compile("zhangsan" ); Console.WriteLine(iszhangsan); Console.ReadKey();
也可以對樹的結(jié)構(gòu)進(jìn)行解析,Expression<Func <string, bool>> filter = x => x == "zhangsan" ; //我們可以對這個(gè)表達(dá)式樹進(jìn)行解析 //從名稱也可以看出來二叉樹 BinaryExpression body = (BinaryExpression)filter.Body; ParameterExpression left = (ParameterExpression)body.Left; ConstantExpression right = (ConstantExpression)body.Right; string type = body.NodeType.ToString(); Console.WriteLine("樹的左邊是{0},節(jié)點(diǎn)符號(hào){1},樹的右邊{2}" ,left,type,right);
可以看到存在一個(gè)表達(dá)式樹,這個(gè)表達(dá)式樹就存儲(chǔ)了上面的linq 語句想要表達(dá)的行為信息,而provider則可以顯示出接下來就翻譯這個(gè)行為信息成為新的可執(zhí)行代碼的程序,如linq to sqlserverprovider (自帶) linq to Oracle等。而之所以要進(jìn)行這樣由C#代碼翻譯成表達(dá)式樹數(shù)據(jù)信息在翻譯成可執(zhí)行代碼的原意在于。你最終是要生成sql語句串通過網(wǎng)絡(luò)發(fā)送到遠(yuǎn)程數(shù)據(jù)庫在查詢出結(jié)果才可以嘛。
當(dāng)然如何從上面的代碼得出表達(dá)式樹,又怎么分析得出合適的sql語句就不在討論范圍之內(nèi)了,這里面有比較復(fù)雜的算法。對于linq to objects 返回的則是IEnumerable 里面就不需要什么表達(dá)式樹來存儲(chǔ)信息了,因?yàn)楸旧砭褪轻槍μ幱谕粔K內(nèi)存中的數(shù)據(jù)進(jìn)行查詢,直接邏輯查找就可以了。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注