2013-01-14 85 views
4

我正在使用PredicateBuilder創建一個動態的Where子句來查詢DataTable中的數據。我有一個包含我需要搜索的列名和值的字典。我只是迭代字典,如果關鍵字匹配列名稱,然後將該關鍵字和值添加到謂詞。一切似乎工作正常,直到對數據表運行實際查詢,我得到零記錄:(但如果我用p => p [「年」] =「2010」替換動態謂詞,我得到記錄回到下面的代碼:PredicateBuilder返回零記錄

var objectList = table.AsEnumerable(); 
Func<DataRow, bool> predicate = GetPredicate(parms, table.Columns); 

var list1 = objectList.Where(predicate).ToList(); 

private static Func<DataRow, bool> GetPredicate(Dictionary <string, string> parms, DataColumnCollection dataColumnCollection) 
    { 
     var predicate = PredicateBuilder.False<DataRow>(); 
     foreach (var parm in parms) 
     { 
      if (dataColumnCollection.Contains(parm.Key)) 
      { 
       var copy = parm; 
       predicate = predicate.And(p => p[copy.Key] == copy.Value); 
      } 
     } 
     return predicate.Compile(); 
    } 

任何幫助,將不勝感激:)

+0

可能的重複[爲什麼此代碼與PredicateBuilder不工作?](http://stackoverflow.com/questions/5302382/why-is-this-code-with-predicatebuilder-not-working) –

+1

@AhmadMageed這是一個完全不同的問題。 – svick

+0

@AhmadMageed我在添加鍵值和臨時變量之前將它們包含在謂詞中,沒有幫助:( –

回答

8

你開始與false然後加入and條款。

false && ...總是返回false,因此您的Where子句將永遠不會匹配任何內容。

開始嘗試用:

var predicate = PredicateBuilder.True<DataRow>(); 

ALSO:

您關閉了循環變量,這意味着所有的謂詞將在parms使用最後parm

你可以在你的循環創造一個本地副本解決這個問題:

foreach(var parm in parms) 
{ 
    if (dataColumnCollection.Contains(parm.Key)) 
    { 
    var copy = parm; 
    predicate = predicate.And(p => p[ copy.Key ] == copy.Value); 
    } 

UPDATE:

DataRow[ key ]object型的,所以在p[ copy.Key ] == copy.Value,等於運算符是對象引用相等,而不是字符串相等。

您可以通過指定String.Equals解決這個問題:

predicate = predicate.And(p => String.Equals(p[ copy.Key ], copy.Value)); 

有趣的是,這個例子表明,你可以有string內容相同的多個實例。

+0

我在發佈之前做過。仍然沒有記錄:( –

+0

仍然沒有運氣:( –

+0

)如果你通過一個空字典作爲'parms'?你應該得到整個'objectList'的一個副本。 –