Reputation: 21162
I want to accept a string array of where conditions from the client like field == value
.
It would be really nice to create a specification object that could accept the string in the constructor and output a lambda expression to represent the Where clause. For example, I could do the following:
var myCondition = new Specification<Product>( myStringArrayOfConditions);
var myProducts = DB.Products.Where( myCondition);
How could you turn "name == Jujyfruits"
into DB.Products.Where(p => p.name == "JujyFruits")
?
Upvotes: 8
Views: 8578
Reputation: 172200
You can use
Product.name
from the string name
andExpression
class to manually create a lambda expression.Note that the following code example will only work for Equals (==)
operations. However, it is easy to generalize to other operations as well (split on whitespace, parse the operator and choose the appropriate Expression instead of Expression.Equal
).
var condition = "name == Jujyfruits";
// Parse the condition
var c = condition.Split(new string[] { "==" }, StringSplitOptions.None);
var propertyName = c[0].Trim();
var value = c[1].Trim();
// Create the lambda
var arg = Expression.Parameter(typeof(Product), "p");
var property = typeof(Product).GetProperty(propertyName);
var comparison = Expression.Equal(
Expression.MakeMemberAccess(arg, property),
Expression.Constant(value));
var lambda = Expression.Lambda<Func<Product, bool>>(comparison, arg).Compile();
// Test
var prod1 = new Product() { name = "Test" };
var prod2 = new Product() { name = "Jujyfruits" };
Console.WriteLine(lambda(prod1)); // outputs False
Console.WriteLine(lambda(prod2)); // outputs True
About the constructor thing: Since Func<T, TResult>
is sealed, you cannot derive from it. However, you could create an implicit conversion operator that translates Specification<T>
into Func<T, bool>
.
Upvotes: 15
Reputation: 126
We've recently discovered the Dynamic LINQ library from the VS2008 sample projects. Works perfectly to turn string based "Where" clauses into expressions.
Upvotes: 3
Reputation: 6713
You need to turn your search term into a predicate. Try something like the following:
string searchString = "JujyFruits";
Func<Product, bool> search = new Func<Product,bool>(p => p.name == searchString);
return DB.Products.Where(search);
Upvotes: 0