I use linqToEntities
and would like to add OR
condition dynamically.
I know that there is a great library PredicateBuilder
by brother Albahari and it can solve my task, but I cannot use it.
My conditions looks like this:
IEnumerable<Condition> conditions = new List<Condition>()
{
new Condition(){IdReference = 1, TableName = "Table1" },
new Condition(){IdReference = 2, TableName = "Table2" },
new Condition(){IdReference = 3, TableName = "Table3" },
// and so on
};
What I have is:
var histories = db.History as IQueryable<History>;
foreach (var cond in conditions)
{
//What code should be here to be translated into:
/*
histories = histories
.Where(h => h.IdReference == 1 && h.TableName =="Table1"
|| h.IdReference == 2 && h.TableName == "Table2"
|| h.IdReference == 3 && h.TableName == "Table3");
// and so on
*/
}
However, I do not know in advance how many conditions
would be.
How is it possible to add OR
conditions dynamically from IEnumerable<Condition>
?
Not sure what's the problem with using predicate builder - it doesn't have to be LINQ Kit package, the so called predicate builder is usually a single static class with 2 extension methods - like Universal Predicate Builder or my own PredicateUtils
from Establish a link between two lists in linq to entities where clause and similar.
Anyway, once you want it, of course it could be built using just plain Expression class static methods.
Add the following in order to eliminate the need of writing Expression.
before each call:
using static System.Linq.Expressions.Expression;
and then use something like this:
if (conditions.Any())
{
var parameter = Parameter(typeof(History));
var body = conditions
.Select(condition => Expression.Constant(condition))
.Select(condition => Expression.AndAlso(
Expression.Equal(
Expression.PropertyOrField(parameter, nameof(History.IdReference)),
Expression.Convert(
Expression.PropertyOrField(condition, nameof(Condition.IdReference))
, Expression.PropertyOrField(parameter, nameof(History.IdReference)).Type)
),
Expression.Equal(
Expression.PropertyOrField(parameter, nameof(History.TableName)),
Expression.Convert(
Expression.PropertyOrField(condition, nameof(Condition.TableName))
, Expression.PropertyOrField(parameter, nameof(History.TableName)).Type)
)
))
.Aggregate(Expression.OrElse);
var predicate = Lambda<Func<History, bool>>(body, parameter);
histories = histories.Where(predicate);
}