0

I'm trying to use Expression.NotEqual() (here)

But I can't understand how to use the methodInfo.

I'm trying to make a comparison to a possible bool?.

This is the property that I want to evaluate, which was added to database after release (creating null's as well as true and false:

public bool? Deactivated { get; set; } = false;

I'm using a working expression builder with generic that accepts parameters sent in a object that has a List of WhereParameters like below:

List<WhereParameters> whereList = new List<WhereParameters>();

        whereList.Add(new WhereParameters
        {
            field = "ID",
            field_Value_Relation = "notEqual",
            value = Guid.Empty
        });
        whereList.Add(new WhereParameters
        {
            field = "Deactivated",
            field_Value_Relation = "notEqualorNull", //orNull => nullable
            value = true
        });

These parameters are used in the builder:

 public List<M> getExpression(QueryParameters<M> QueryParams)
    {

        

        //GET TYPE FROM GENERIC M
        Type modelType = QueryParams.modelType;


        //QUERY DB with GENERIC TYPE
        IQueryable<M> queryableData = (IQueryable<M>)QueryParams.db.Set(modelType);

        // Compose the expression tree that represents the parameter to the predicate.  

        //CREATE EXPRESSION PARAMETER
        ParameterExpression pe = Expression.Parameter(typeof(M), "param"); 

        // Create an expression tree that represents the expression 
        //if (QueryParams.whereParameters != null && QueryParams.whereParameters.Count > 0)
        //{

            int w = 0;
        foreach (WhereParameters whereParam in QueryParams.whereParameters) { 
        //BLOCK A.1 WHERE
        //Create Property on the Left of equality
        Expression left1 = Expression.Property(pe, whereParam.field.ToLower());
        //Create Property on the right of equality
        Expression right1 = Expression.Constant(whereParam.value);

            //Expresses the relation between left and right

            //Expression e1;
                switch (whereParam.field_Value_Relation)
                {
                    case "notEqualOrNull":
                        predicateBody = Expression.NotEqual(left1, right1, true , ????????);
                        break;
                }
}

It is throwing a System.InvalidOperationException: The binary operator NotEqual is not defined for the types 'System.Nullable`1[System.Boolean]' and 'System.Boolean'.

I don't know how to make this work with nullables. I understood the islifted param, but can't manage to understand what to send in the last parameter of Expression.NotEqual, as MethodInfo. Can someone please show me examples on how this can be done?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Diogo Almeida
  • 124
  • 2
  • 12
  • Maybe check if the type is nullable and add a pre-check? If it has a value, then you can proceed with the nullable's value. – Haytam Aug 21 '20 at 13:58
  • This was a field added in a BaseModelObject that is hinerited by all model tables, and because of that,all tables in db have this field with null, true and false. This is a generic table search generator, that has this field as searchable. If this field is searched I cannot, not search... so I have to use the nullable field in the querygenerator, wich isn't capable of digesting it. I'm looking for a way for the generator to accept it as is, if possible. Or else I have to update alllllll fields in database (wich I'm trying to avoid) :-S – Diogo Almeida Aug 21 '20 at 14:07

1 Answers1

0

Encountered an answer here

My debug code before refactoring (maintain everything, just changing the Switch, case):

                 case "notEqualOrNull":
             
                       //this block will be promoted out of here
                        var field = whereParam.field;
                        var fieldValue = whereParam.value;
                        var prop = modelType.GetProperty(field);
                        var isNullable = prop.PropertyType.IsNullableType();
                       
                        var member = Expression.Property(pe, field);


                        var filter1 =
                        Expression.Constant(Convert.ChangeType(fieldValue, member.Type.GetGenericArguments()[0]));
                        Expression typeFilter = Expression.Convert(filter1, member.Type);
                        
                        //this is a proxy of the code that will be here after refactoring
                        andPredicateBody = Expression.NotEqual(left1, typeFilter);
                        predicateBody = Expression.OrElse(predicateBody, andPredicateBody);

                        break;

This will be refactored, in order to be more general, once it can test all nullables. the only change in the 'switch case' will be the var right1 or typefilter.

Diogo Almeida
  • 124
  • 2
  • 12
  • So, in other words, you're not using the `isLifted` parameter or the `IsLifted` property of the expression. – Zev Spitz Aug 23 '20 at 19:27
  • @ZevSpitz correct. Converted to nullable before. But if someone answers I will be glad to make it the right answer to the question. This is a workaround. – Diogo Almeida Aug 24 '20 at 17:00