Skip to content

Cannot CompileProjection for a mapping derived types between abstract classes with .Include() #801

@Tommsy64

Description

@Tommsy64

Description

When trying to create a mapping between abstract base classes and including their derived concrete implementations, Mapster throws an exception during CompileProjection(). There appears to be an issue in the expression tree generation.

Environment

  • Mapster version: 7.4.0
  • Mapster.EFCore 5.1.1
  • .NET version: net9.0
  • EF Core version: 9.0.4

I have tried Mapster 7.4.2-pre02 with net9.0 and net8.0 as well.

Steps to Reproduce

  1. Define the following class hierarchy:
public abstract class PocoA
{
    public int Id { get; set; }
}

public class PocoDerived : PocoA
{
    public int DerivedVal { get; set; }
}

public abstract class DtoA
{
    public int Id { get; set; }
}

public class DtoDerived : DtoA
{
    public int DerivedVal { get; set; }
}
  1. Configure the mapping:
config.NewConfig<PocoA, DtoA>()
    .Include<PocoDerived, DtoDerived>();
  
config.CompileProjection();

Alternatively, edit the WhenIncludeDerivedClasses test in Mapster.Tests so that the Compile() lines are CompileProjection();

Expected Behavior

The mapping should compile successfully, allowing for projection between these types.

Actual Behavior

An exception is thrown during CompileProjection():

Unhandled exception. Mapster.CompileException: Error while compiling
source=Backend.Services.Models.PocoA
destination=Backend.Services.Models.DtoA
type=Projection
 ---> System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.UnaryExpression' to type 'System.Linq.Expressions.NewExpression'.
   at Mapster.Adapters.ClassAdapter.CreateInlineExpression(Expression source, CompileArgument arg)
   at Mapster.Adapters.BaseAdapter.CreateInlineExpressionBody(Expression source, CompileArgument arg)
   at Mapster.Adapters.BaseAdapter.CreateExpressionBody(Expression source, Expression destination, CompileArgument arg)
   at Mapster.Adapters.BaseAdapter.CreateAdaptFunc(CompileArgument arg)
   at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
   --- End of inner exception stack trace ---
   at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
   at Mapster.TypeAdapterConfig.CreateMapExpression(TypeTuple tuple, MapType mapType)
   at Mapster.TypeAdapterConfig.CreateProjectionCallExpression(TypeTuple tuple)
   at Mapster.TypeAdapterConfig.CompileProjection()

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions