hazzik / DelegateDecompiler

A library which is able to decompile a delegate or a method body to its lambda representation
MIT License
522 stars 62 forks source link

Decompiling computeds that take nullable enums fails #160

Closed NetMastr5 closed 3 years ago

NetMastr5 commented 4 years ago

When you call decompile when a nullable enum computed is part of the exrepssion tree an error is thrown. The same calls work if the enum is not nullable.


Expression of type 'System.Int32' cannot be used for constructor parameter of type 'VM.Core.Entities.TSD_DUT_DET+TheType'

~~~Stack Trace~~~
   at DelegateDecompiler.Processor.Process()
   at DelegateDecompiler.Processor.Process(VariableInfo[] locals, IList`1 args, Instruction instruction, Type returnType)
   at DelegateDecompiler.MethodBodyDecompiler.DecompileConcrete(MethodInfo method, IList`1 args)
   at DelegateDecompiler.MethodBodyDecompiler.Decompile(MethodInfo method, Type declaringType)
   at DelegateDecompiler.DecompileExtensions.<>c__DisplayClass6_0.<.cctor>b__1()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at DelegateDecompiler.DecompileExtensions.Decompile(MethodInfo method, Type declaringType)
   at DelegateDecompiler.DecompileExpressionVisitor.Decompile(MethodInfo method, Expression instance, IList`1 arguments)
   at DelegateDecompiler.DecompileExpressionVisitor.VisitMember(MemberExpression node)
   at DelegateDecompiler.DecompileExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at DelegateDecompiler.DecompileExpressionVisitor.Decompile(Expression expression)
   at DelegateDecompiler.DecompiledQueryProvider.CreateQuery[TElement](Expression expression)
   at DelegateDecompiler.DecompileExtensions.Decompile[T](IQueryable`1 self)
   at VM.WebForm1.Page_Load(Object sender, EventArgs e) in C:\Projects_TFS\VM-Sprint\VM\WebForm1.aspx.cs:line 17

~~~Environment~~~
EntityFramework 6.2.0
.Net Framework 4.7.2
Oracle.ManagedDataAccess 19.3.1
Oracle.ManagedDataAccess.EntityFramework 19.3.0
DelegateDecompiler 0.28.0
DelegateDecompiler.EntityFramework 0.28.0

~~~Entities~~~
[Table("TSD_DUT_DET", Schema = "TSD_MKTG")]
public class TSD_DUT_DET
{

    public enum TheType
    {
        ONE = 1,
        TWO = 2,
        THREE = 3
    }

    [Key]
    [Column("TSD_DUT_DET_ID")]
    public decimal ID { get; set; }

    [Column("TYP")]
    public int? _type { get; set; }

    [NotMapped]
    [Computed]
    public TheType? type {
        get => (TheType?)this._type;
        set => this._type = value == null ? null : (int?)value;
    }
}

[Table("TSD_DUT_DET_MDL", Schema = "TSD_MKTG")]
public class TSD_DUT_DET_MDL
{

    public enum TheType
    {
        ONE = 1,
        TWO = 2,
        THREE = 3
    }

    [Key]
    [Column("TSD_DUT_DET_MDL_ID")]
    public decimal ID { get; set; }

    [Column("TYP")]
    public int _type { get; set; }

    [NotMapped]
    [Computed]
    public TheType type {
        get => (TheType)this._type;
        set => this._type = (int)value;
    }
}

~~~Successful Commands For Not Nullable Enum And Generated SQL~~~
context.TSD_DUT_DET_MDL.Where(x => x.type == Core.Entities.TSD_DUT_DET_MDL.TheType.ONE).Decompile().FirstOrDefault();
SELECT
"Extent1"."TSD_DUT_DET_MDL_ID" AS "TSD_DUT_DET_MDL_ID",
"Extent1"."TYP" AS "TYP"
FROM "TSD_MKTG"."TSD_DUT_DET_MDL" "Extent1"
WHERE (1 = "Extent1"."TYP") AND (ROWNUM <= (1) )

context.TSD_DUT_DET_MDL.Select(x => new { type = x.type }).Where(x => x.type == Core.Entities.TSD_DUT_DET_MDL.TheType.ONE).Decompile().FirstOrDefault();
SELECT
"Extent1"."TYP" AS "TYP"
FROM "TSD_MKTG"."TSD_DUT_DET_MDL" "Extent1"
WHERE (1 = "Extent1"."TYP") AND (ROWNUM <= (1) )

context.TSD_DUT_DET_MDL.Select(x => new { type = x.type }).Decompile().FirstOrDefault();
SELECT
"c"."TYP" AS "TYP"
FROM "TSD_MKTG"."TSD_DUT_DET_MDL" "c"
WHERE (ROWNUM <= (1) )

~~~Failed Commands For Nullable Enum~~~
context.TSD_DUT_DET.Where(x => x.type == Core.Entities.TSD_DUT_DET.TheType.ONE).Decompile().FirstOrDefault();
context.TSD_DUT_DET.Select(x => new { type = x.type }).Where(x => x.type == Core.Entities.TSD_DUT_DET.TheType.ONE).Decompile().FirstOrDefault();
context.TSD_DUT_DET.Select(x => new { type = x.type }).Decompile().FirstOrDefault();

I also changed the underlying int value on the TSD_DUT_DET_MDL entity to int?, and it still works.
I also changed the underlying int? value on the TSD_DUT_DET entity to int, and it still throws the same error.
hazzik commented 2 years ago

Released in 0.30.0