问题
Typically a dynamic linq query with string can use a substitution value such as:
result =
db.Persons.Where("Name == @1", "John");
I have an unknown number of strings that I want to pass into the Where
clause. I have no problem with integers, but the API cannot seem to handle a string without a substitution value.
Does anyone know a way around this? I created a concatenated string for my Where
statement, so I can add "@1" or whatever, but I cannot add parameters to the Where()
so I am stuck.
Thanks!
回答1:
I creating a concatenated string for my where statement, so i can add "@1" or whatever, but I cannot add parameters to the Where() so I am stuck.
Yes, you can. The second argument of the Where
method is params object[] values
, so you just need to pass an array of objects.
For instance, assuming you have the property names and values in a dictionary, you could do something like this:
var dic = new Dictionary<string, object>
{
{ "Name", "John" },
{ "Age", 30 },
{ "City", "New York" }
};
...
var conditions = dic.Keys.Select(
(key, idx) =>
string.Format("{0} == @{1}", key, idx));
string predicate = string.Join(" And ", conditions);
object[] values = dic.Values.ToArray();
result = db.Persons.Where(predicate, values);
回答2:
I think I can see what you mean about the string substitution problem.
Here are a couple of alternatives to explore. Thomas Petricek's solution, if you can follow it, is especially interesting:
Building [Dynamic] LINQ Queries at Runtime in C#
http://tomasp.net/articles/dynamic-linq-queries.aspx
Dynamically Composing Expression Predicates using PredicateBuilder
http://www.albahari.com/nutshell/predicatebuilder.aspx
See also http://blogs.msdn.com/b/mattwar/archive/2006/05/10/594966.aspx
回答3:
I have made something for this. Using David Fowlers DynamicLinq project in combination with a PredicateBuilder you can build predicates from a Generic IQueryable and build them. Special thanks to some StackOverflow answer that gave me this line to convert from
Func<dynamic, dynamic>
to:
Expression<Func<T, bool>>
Implmentation..
private static Expression<Func<T, bool>> GetFuncTbool<T>(IQueryable source, Func<dynamic, dynamic> expressionBuilder)
{
ParameterExpression parameterExpression = Expression.Parameter(GetElementType(source), expressionBuilder.Method.GetParameters()[0].Name);
DynamicExpressionBuilder dynamicExpression = expressionBuilder(new DynamicExpressionBuilder(parameterExpression));
Expression body = dynamicExpression.Expression;
return Expression.Lambda<Func<T, bool>>(body, parameterExpression);
}
This allows "or" joining generic Predicates in a loop like this...
predicateToAdd = query.DynamicWhereForPredicateBuilder(z => z[columnName].Contains(dataTablesRequest.sSearch)); //contains or
The full write up is here and the full demonstration is in the source at MvcCms.CodePlex
来源:https://stackoverflow.com/questions/3937435/dynamic-linq-and-substitution-values-with-unknown-number