0

I use Entity Framework 5 and i've a dynamic linq query. But i need i have to connect two conditions with "OR" operator. For example i can use this in normal sql text as this.

SELECT * FROM Products WHERE 
(Keywords LIKE '%keyw1%' AND Keywords LIKE '%keyw2%') OR (ProdName LIKE '%ProdName%')

My linq query below. But i need create where conditions dynamically. How can i do this?

var prodQuery = from p in _db.Products
    select p;

searchText.Split(' ')
    .ForEach(
        s =>
            prodQuery =
                prodQuery.Where(
                    p => p.Product.Keywords.Contains(s)));

//i need here "OR" operator. I have to connect this line with "OR" to upper condition
prodQuery = prodQuery.Where(p => p.ProdName.Contains("test prod"))  
Yargicx
  • 1,704
  • 3
  • 16
  • 36

2 Answers2

0

Have you tried something like:

searchText.Split(' ')
    .ForEach(s => prodQuery = prodQuery
        .Where(p => p.Product.Keywords.Contains(s)) || p.ProdName.Contains("test prod")
    );

Heres a cleaner version of it that should work for you:

string[] searchTerms = searchText.Split(' ');
var prodQuery = _db.Products.Any(p => 
    p.Product.Keywords.Any(k => searchTerms.Contains(k)) 
    || searchTerms.Contains(p.ProdName)
);
Brad C
  • 2,868
  • 22
  • 33
0

What you should do is to build your query condition in an expression tree and then apply it to your linq object.

You can use this PredicateBuilder class to do so.

public static class PredicateBuilder
{
    public static Expression<Func<T, bool>> True<T>() { return f => true; }
    public static Expression<Func<T, bool>> False<T>() { return f => false; }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
          (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>> (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
    }
}

And Now Your Code:

var prodQuery = from p in _db.Products
   select p;

var condition = PredicateBuilder.False<Product>();

searchText.Split(' ')
    .ForEach(s => condition = condition.And(p => p.Product.Keywords.Contains(s)));

condition = condition.Or(p => p.ProdName.Contains("test prod"));
prodQuery = prodQuery.Where(condition);
Hosein
  • 581
  • 1
  • 7
  • 29