Zachary Scott
Zachary Scott

Reputation: 21162

Entity Framework 4: convert a string condition to a lambda expression?

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

Answers (3)

Heinzi
Heinzi

Reputation: 172200

You can use

  • Reflection to get the Property Product.name from the string name and
  • the LINQ Expression 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

Jim Ross
Jim Ross

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.

This link will get you there.

Upvotes: 3

Paul Suart
Paul Suart

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

Related Questions