Linq to Sql : 動態構造Expression進行動態查詢

iDotNetSpace發表於2010-01-29

    前一篇在介紹動態查詢時,提到一個問題:如何根據使用者的輸入條件,動態構造這個過濾條件表示式呢?
Expressionbool>> predicate t => t.ProductName.Contains("che") && t.UnitPrice >= 22;

    理想情況下,我希望可以像下面這樣來構造predicate,這樣,我們就可以使用&、| 、&=、|=來任意拼接過濾條件了:

   1: Expressionbool>> predicate = null;
   2: predicate &= (t => t.ProductName.Contains("che")) | (t => t.UnitPrice >= 22);

    但是理想與現實之間,似乎總有不可逾越的鴻溝……

 

    前面的程式碼中,我們總是要寫一常串Expression>,寫得都有點兒煩了,我妄想自定義一個型別,這樣就不用每次都寫這麼長了,然後再針對這個自定義型別再進行運算子過載……然後我 發現,Expression是密封型別(sealed),不給過載,沒辦法,只好老老實實的寫,運算子過載也泡湯了。

 

   無奈之下,只好實現了下面的這種方式,勉強湊合用著:

   1: ExpressionProductExt, bool>> predicate = null;
   2: predicate = predicate.AndAlso(p => p.CompanyName.Length > 2)
   3:      .OrElse((Products p) => p.ProductName.Contains("che"))
   4:      .AndAlso((Products p) => p.UnitPrice >= 22);

    運算得到的結果如下:p => (((p.CompanyName.Length > 2) || p.ProductName.Contains("che")) && (p.UnitPrice >= 22))

    有了這個OrElse和AndAlso擴充套件,我們就可以對Expression>為所欲為了……

    不過跟之前文章中提到的一樣,這裡有個限制:雖然我們的Expression中,第一個可以凡泛型引數可以傳任意值(譬如傳ProductExt或 Products或其他的,可以不必要求是同一種型別),但條件中用到的物件屬性(譬如CompanyName、ProductName、 UnitPrice ),必須在T中存在同名屬性。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-626327/,如需轉載,請註明出處,否則將追究法律責任。

相關文章