PredicateBuilder返回零记录

时间:2013-01-14 16:40:00

标签: c# linq where predicate predicatebuilder

我正在使用PredicateBuilder创建一个动态Where子句来查询DataTable中的数据。我有一个包含我需要搜索的列名和值的字典。我只是迭代字典,如果键匹配列名,则将该键和值添加到谓词。一切似乎工作正常,直到对数据表运行实际查询,我得到零记录:(但如果我用p => p [“年”] ==“2010”替换动态谓词,我得到记录回来。这是代码:

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();
    }

非常感谢任何帮助:)

1 个答案:

答案 0 :(得分:8)

您从false开始,然后添加and子句。

false && ...始终返回false,因此您的Where子句永远不会匹配任何内容。

尝试从:

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

ALSO:

您正在关闭循环变量,这意味着您的所有谓词都将使用parm中的最后一个parms

您可以通过在循环中创建本地副本来解决此问题:

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

<强>更新

DataRow[ key ]的类型为object,因此在p[ copy.Key ] == copy.Value中,相等运算符是对象引用相等,而不是字符串相等。

您可以通过指定String.Equals

来解决此问题
predicate = predicate.And( p => String.Equals( p[ copy.Key ], copy.Value ) );

有趣的是,此示例显示您可以拥有具有相同内容的多个string实例。