PredicateBuilder返回零记录
我正在使用PredicateBuilder创建一个动态Where子句来查询DataTable中的数据。 我有一个包含我需要搜索的列名和值的字典。 我只是迭代字典,如果键匹配列名,则将该键和值添加到谓词。 一切似乎工作正常,直到对数据表运行实际查询,我得到零记录:(但如果我用p => p [“年”] ==“2010”替换动态谓词,我得到记录回来。这是代码:
var objectList = table.AsEnumerable(); Func predicate = GetPredicate(parms, table.Columns); var list1 = objectList.Where(predicate).ToList(); private static Func GetPredicate(Dictionary parms, DataColumnCollection dataColumnCollection) { var predicate = PredicateBuilder.False(); 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(); }
任何帮助将不胜感激:)
你从false
开始,然后添加and
子句。
false && ...
总是返回false
,所以你的Where
子句永远不会匹配任何东西。
尝试从以下开始:
var predicate = PredicateBuilder.True();
也:
您正在关闭一个循环变量,这意味着您的所有谓词都将使用参数中的最后一个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
实例。