PredicateBuilder returning zero records

狂风中的少年 提交于 2019-12-10 15:21:09

问题


I'm using PredicateBuilder to create a dynamic Where clause to query data from a DataTable. I have a Dictionary that contains my column names and values I need to search for. I'm simply iterating over the dictionary, if the key matches a column name, then add that key and value to the predicate. Everything seems to work fine until the actual query is run against the datatable, I get zero records back:( But if I replace the dynamic predicate with something like p => p["Year"] == "2010", I get records back. Here's the code:

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

Any help would be greatly appreciated:)


回答1:


You're starting with false and then adding and clauses.

false && ... always returns false, so your Where clause will never match anything.

Try starting with:

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

ALSO:

You are closing over a loop variable, which means all your predicates will use the last parm in parms.

You can fix this by creating a local copy in your loop:

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 ] is of type object, so in p[ copy.Key ] == copy.Value, the equality operator is object reference equality, not string equality.

You can fix this by specifying String.Equals:

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

Interestingly, this example shows that you can have multiple instances of string with the same contents.



来源:https://stackoverflow.com/questions/14322669/predicatebuilder-returning-zero-records

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!