2011-08-15 59 views
3

我想在運行時使用http://www.albahari.com/nutshell/predicatebuilder.aspx中的PredicateBuilder動態創建一個linq表達式。如何使用多個嵌套的「ands」和「ors」創建linq謂詞

我目前有一種方法,它接受一個標準對象列表,然後將這些對象解析爲多個謂詞,如此post中所述。

所以目前,我的代碼支持以下情形:

WHERE 
    ((a == <val1>) AND (b == <val2>) AND (c == <val3>)) 
OR 
    ((a == <val4>) AND (b == <val2>) AND (c == <val3>)) 

但我需要它這樣的工作:

WHERE 
    ((a == <val1> OR a == <val4>) AND (b == <val2>) AND (c == <val3>)) 
OR 
    ((a == <val7>) AND (b == <val5>) AND (c == <val6>)) 

我怎樣才能讓這個我可以「羣」兩「ORs」在一起,以便邏輯正確流動?我不想要「a或a和b和c」,我需要「(a或a)和b和C」。

回答

4

這些謂詞的「動態」方面根本不明確。當你可以用&&||表達式(當然有適當的括號)組裝所需的表達式時,爲什麼還要用PredicateBuilder

在任何情況下,這裏的完成你想要PredicateBuilder什麼辦法:以產生最終謂詞

var p1 = PredicateBuilder.False<Foo>() 
         .Or(foo => foo.A == <val1>) 
         .Or(foo => foo.A == <val4>) 
         .And(foo => foo.B == <val2>) 
         .And(foo => foo. C == <val3>); 

var p2 = PredicateBuilder.False<Foo>() 
         .Or(foo => foo.A == <val7>) 
         .And(foo => foo.B == <val5>) 
         .And(foo => foo.C == <val6>); 

var finalPredicate = p1.Or(p2); 

的想法是創建一個單獨的「簡單」的表情,然後最後OR在一起。

+0

我想我不明白當linq正在執行操作順序時應用的規則。我假定一個「Or()。Or()。和()。和()」的語句會產生類似於「a是1或(a是4,b是2和c是3)」的語句。知道要「或」a的在一起? –

+0

只需按照方法調用,你會看到如何:例如,'p1 =(((((First)OR(Second))AND Third)AND Fourth)'這是相同的作爲你定義的布爾代數規則。順便說一句,你可能也想看[運算符優先級和關聯性](http://msdn.microsoft.com/en-us/library/aa691323(v = vs。 71).aspx)指導如何做到「正常」的方式。當需要覆蓋默認優先級時,只需加上括號即可。 – Ani