Question

I have a Dictionary<string,object> of search terms and values. In this case the term is the key. An example is:

var args = new Dictionary<string,object>() {{"name","joe"},
                                            {"occupation","salesman"}};

I am using the PredicateBuilder to build the Where clause and it works, but I was wondering if there was a more concise way to do it with the Dictionary instead of having to call if(args.ContainsKey(...) for every search term in the Dictionary? This is how I am doing it now:

List<Person> persons;
var predicate = PredicateBuilder.False<Person>();

if (args.ContainsKey("name"))
{
    string name = args["name"].ToString();
    predicate = predicate.Or(x => x.name == name);
}


if (args.ContainsKey("name"))
{
    string age = args["age"].ToString();
    predicate = predicate.Or(x => x.age == age);
}

persons = _context.Persons.AsExpandable().Where(predicate).ToList();

Also, if I declare string name outside the if block, resharper says Access to modified closure, but does it matter in this case? For example

string name;

if (args.ContainsKey("name"))
{
    name = args["name"].ToString();
    predicate = predicate.Or(x => x.name == name); //Access to modified closure
}

But in the above, I am not modifying name anywhere, so why does it tell me this?

I am new to PredicateBuilder, so if someone an explain what PredicateBuilder.False<Person>() means as opposed to PredicateBuilder.True<Person>() and what does the Compile method do?

Était-ce utile?

La solution

Also, if I declare string name outside the if block, resharper says Access to modified closure, but does it matter in this case?

The code will still work despite the fact that your code generates this warning. This happens to not be a problem unless you modify the name variable some time before you actually invoke that closure. In the code you've shown you never use it again, so it wouldn't be a problem, but if you ever modified it in code shown after the code you have it would be a problem.

Why do you want to do this in the first place? For starters, I don't really see the point of the variable to begin with. Why not just write: x => x.name == args["name"]? If you did want a local variable for this, why would you want to scope it at the higher level? You should always scope any variable at the lowest scope possible while still allowing it to be accessed where it needs to be. You shouldn't be modifying it outside the if, so don't expose it outside the if.

I am new to PredicateBuilder, so if someone an explain what PredicateBuilder.False() means as opposed to PredicateBuilder.True()

It creates an expression that resolves to false if invoked instead of true...

Note that false || variable is equivalent to just variable. The reason you want to initialize it to false is to avoid special-casing the first actual check you want by initializing the PredicateBuilder there. It allows each of your variables to be consistent and always OR whatever it is that the predicatebuilder currently resolves to.

what does the Compile method do?

It compiles the expression into a delegate that can be invoked.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top