Reputation: 33
I want to create dynamic query builder using LINQ to SQL
For that, I created my interface that add each dynamic condition in
List<Expression<Func<T,bool>>>
Interface looks like :
public interface IExpression<T>
{
IExpression<T> AddWhere(Expression<Func<T,bool>> whereCriteria);
}
Now I want to combine all expression in list and construct where clause with "and" condition and execute query.
I tried combining expression but not succeeded in that attempt.
Can anyone please help ? or please suggest any other alternative.
Upvotes: 3
Views: 2712
Reputation: 63722
The easiest way is to use PredicateBuilder: http://www.albahari.com/nutshell/predicatebuilder.aspx
Basically, all you have to do is make use of this helper class:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
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 then you can use it like so:
public static Expression<Func<Product, bool>> ContainsInDescription (
params string[] keywords)
{
var predicate = PredicateBuilder.False<Product>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or (p => p.Description.Contains (temp));
}
return predicate;
}
(both the code and the example are taken from the link above, I just posted it here in case the link doesn't work sometime).
Your particular scenario is somewhat complicated by the fact that your interface doesn't use generics. Could you show a bit more of the relevant code, so that I can help tailor this solution better to your actual needs?
Upvotes: 7