In Expression Trees, why is a conversion required?

c# entity-framework expression-trees

Question

zzz-5 to zzz I questioned five minutes ago, and it's evident that the following code raises an exception that says

Unhandled Exception: System.InvalidOperationException: The binary operator Equal is not defined for the types 'System.Nullable`1[System.Int32]' and 'System.Int32'.

Code

public static void GetResultCollection<T>() {
        AccrualTrackingEntities db = new AccrualTrackingEntities();
        var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

        int? ItemTypeValue = 1;

        var param = Expression.Parameter(typeof(T));

        var lambda = Expression.Lambda<Func<T, bool>>(
            Expression.Equal(
                Expression.Property(param, "ProcInstId"),
                Expression.Constant(ItemTypeValue)),
            param);

        var list = result.Where(lambda).ToList();
    }

However, this code specifically specifies the type inExpression.Constant does it?

class Program {
    public static void GetResultCollection<T>() {
        AccrualTrackingEntities db = new AccrualTrackingEntities();
        var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

        int? ItemTypeValue = 1;

        var param = Expression.Parameter(typeof(T));

        var lambda = Expression.Lambda<Func<T, bool>>(
            Expression.Equal(
                Expression.Property(param, "ProcInstId"),
                Expression.Constant(ItemTypeValue, typeof(int?))),
            param);

        var list = result.Where(lambda).ToList();
    }

What is why is the question?Expression.Constant unable to automatically convert toint? to ...int?

1
7
5/23/2017 11:45:49 AM

Accepted Answer

Expression trees operate at a lower level than regular source code; in fact, you might say that they operate at the output level of the compiler as opposed to the input. Therefore, even if there is an implicit conversion fromint to int? Every time the compiler applies that conversion for a regular method in C#, it must be expressed in IL, which means it must also be present in an expression tree representation.

However, considering that you're attempting to offer an example, yours is a little confusing.int (namely ItemTypeValue.Value ) in place of anint? consistent, and we are unsure about the nature of theItemType either property or.

A brief yet complete illustration of how you'd anticipate things to function would be very beneficial.

Okay, I believe I now agree with you. Unfortunately, if you utilize

int? foo = 1;
Expression.Constant(foo);

after which Expression.Constant(object) is called, which boxes the value offoo . That is whenExpression.Constant not obvious that it was initially anint? since it is now a boxedint . That is just the case. How NET boxing works

int? foo = 1;
object o = foo;
Console.WriteLine(o.GetType()); // Prints System.Int32

that excess ofExpression.Constant defines the expression's general type based on the value provided, creating anint when all you truly want is anint? expression.

Use the overload that enables you to define the type in order to keep the type information properly:

int? foo = 1;
Expression.Constant(foo, typeof(int?));

Although it's still unclear from your inquiry which code functions and which doesn't, possibly this can assist.

15
2/21/2011 3:32:32 PM


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