MapsterMapper/Mapster

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

開放

#801 建立於 2025年5月7日

 (9 則留言) (0 個反應) (0 位負責人)C# (312 個分叉)batch import
help wantedimprovement

倉庫指標

星標
 (3,995 顆星)
PR 合併指標
 (平均合併 12天 15小時) (30 天內合併 10 個 PR)

描述

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()

貢獻者指南