2013-01-14 59 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'的一个副本。 –