Search code examples
c#linqlinq-expressions

Integer contains linq c# but using using expressions


I want to create a dynamic filter for my repositories using linq expressions, I have other filters but i don't know how to make the next one using expressions: (the condition was taked from here)

var result = _studentRepotory.GetAll().Where(s => 
SqlFunctions.StringConvert((double)s.Id).Contains("91")).ToList();

I have a method that receives the value of a property, the propertyName and the filter operator type (enum):

public static class Helper {
    public static Expression<Func<T, bool>> GetExpression<T>(object value, string propertyName, FilterOperatorType FilterType)
    {
        var parameter = Expression.Parameter(typeof(T));
        var property = ExpressionUtils.GetPropertyChild(parameter, propertyName);
        var constValue = Expression.Constant(value);

        BinaryExpression expresion = null;
        switch (FilterType)
        {
            case FilterOperatorType.Equal:
                expresion = Expression.Equal(property, constValue);
                break;
            case FilterOperatorType.Greater:
                expresion = Expression.GreaterThan(property, constValue);
                break;
            case FilterOperatorType.Less:
                expresion = Expression.LessThan(property, constValue);
                break;
            case FilterOperatorType.GreaterOrEqual:
                expresion = Expression.GreaterThanOrEqual(property, constValue);
                break;
            case FilterOperatorType.LessOrEqual:
                expresion = Expression.LessThanOrEqual(property, constValue);
                break;
        }

        var lambda = Expression.Lambda<Func<T, bool>>(expresion, parameter);
        return lambda;
    }
}

So, I want to add a new opertator type Contains that will evaluate if an integer contains some digits, in the first block of code I do it, but I want to do it with linq expressions using generics.

At the end I wil have:

Expression<Func<Student, bool>> where = Helper.GetExpression<Student>("91", "Id",  FilterOperatorType.Contains);
var result = _studentRepotory.GetAll().Where(where).ToList();

The query should return all the students when the Id contains the digits 91.

Please help me, and tell me if you understand.


Solution

  • I'm at 2:00 am and still working on this, the brain works better at that time hehehe, here is the solution for create the expression:

    object value = "91";
    
    var parameter = Expression.Parameter(typeof(Student));
    var property = ExpressionUtils.GetPropertyChild(parameter, "Id");
    var constValue = Expression.Constant(value);
    
    var expressionConvert = Expression.Convert(property, typeof(double?));
    
    var methodStringConvert = typeof(SqlFunctions).GetMethod("StringConvert",
                        BindingFlags.Public | BindingFlags.Static, null,
                        CallingConventions.Any,
                        new Type[] { typeof(double?) },
                        null);
    
    var methodContains = typeof(string).GetMethod("Contains", 
                BindingFlags.Public | BindingFlags.Instance,
                null, CallingConventions.Any,
                new Type[] { typeof(String) }, null);
    
    var expresionStringConvert = Expression.Call(methodStringConvert, expressionConvert);
    var expresionContains = Expression.Call(expresionStringConvert, methodContains, constValue);
    var lambdaContains = Expression.Lambda<Func<Student, bool>>(expresionContains, parameter);
    

    Now you can use lambdaContains in the Where method of the studentRepository