How To create linq Expression dynamically in c# for Contains

entity-framework-core lambda linq reflection

Question

I am trying to create expression dynmically but i could not figure it out... Also dont want to use like this..

if (item.id == 1) filter.AddExpression(c => filterValues.Contains(c.a1));
if (item.id == 2) filter.AddExpression(c => filterValues.Contains(c.a2));
if (item.id == 3) filter.AddExpression(c => filterValues.Contains(c.a3));
if (item.id == 4) filter.AddExpression(c => filterValues.Contains(c.a4));

...

var filtervalues = new List<int>(){1,2,3,4...}
Filter<TestSubject> filter = new Filter<TestSubject>(null);

How can achieve this with iterate... This is a web project and filed ids and their values comes by IQueryCollection converting keys and values to query mysql with entity framework... for Where in clause trying to do this. If another way exist appreciated but for now I have this mighty :) way and could not accomplish...

foreach (var field in QueryFields)
{           
    filter.AddExpression(c => filterValues.Contains(c=>"a"+field.id)); // Trying to do this
}

public class TestSubject 
{
    public int? a1 { get; set; }
    public int? a2 { get; set; }
    public int? a3 { get; set; }
    public int? a4 { get; set; }               
}

public class Filter<TEntity> 
{  
    public Filter(Expression<Func<TEntity, bool>> expression) 
    { 
        Expression = expression; 
    }

    public Expression<Func<TEntity, bool>> Expression { get; private set; }

    public void AddExpression(Expression<Func<TEntity, bool>> newExpression)
    {
        if (newExpression == null) throw new ArgumentNullException(nameof(newExpression), $"{nameof(newExpression)} is null.");

        if (Expression == null) Expression = newExpression;

        var parameter = System.Linq.Expressions.Expression.Parameter(typeof(TEntity));

        var leftVisitor = new ReplaceExpressionVisitor(newExpression.Parameters[0], parameter);
        var left = leftVisitor.Visit(newExpression.Body);

        var rightVisitor = new ReplaceExpressionVisitor(Expression.Parameters[0], parameter);
        var right = rightVisitor.Visit(Expression.Body);

        Expression = System.Linq.Expressions.Expression.Lambda<Func<TEntity, bool>>(System.Linq.Expressions.Expression.AndAlso(left, right), parameter);
    }
}
1
0
2/27/2018 8:55:55 AM

Popular Answer

Thanks for answer was right and my result is like below. For >= and Contains filters.. That i am using for query db with Entity Framework ..

    // >=  
    var parameter = Expression.Parameter(typeof(Cx), "Cx"); // Cx Type.
    var member    = Expression.Property(parameter, "a" + fieldNo); //Cx.ay
    var constant  = Expression.Constant(int.Parse(query[fieldNo.ToString()]));
    Expression body     = Expression.GreaterThanOrEqual(member, Expression.Convert(Expression.Constant(int.Parse(query[.ToString()])), member.Type)); // Contains Conversion for GreaterThanOrEqual not accept int , int?
    var finalExpression = Expression.Lambda<Func<Classified, bool>>(body, parameter); 
    filter.AddExpression(finalExpression);           

    // Contains
    var methodInfo      = typeof(List<int?>).GetMethod("Contains", new Type[] { typeof(int?) }); // Contains Method
    var parameter       = Expression.Parameter(typeof(Cx), "Cx"); // Cx Type.
    var member          = Expression.Property(parameter, "a" + fieldNo); //Cx.ay
    var constant        = Expression.Constant(filterValues);
    Expression body     = Expression.Call(Expression.Constant(filterValues), methodInfo, member);
    var finalExpression = Expression.Lambda<Func<Classified, bool>>(body, parameter);
    filter.AddExpression(finalExpression);
2
3/1/2018 7:32:26 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow