C# 枚举与其整数值之间的自动映射因ReverseMap而失败

C# 枚举与其整数值之间的自动映射因ReverseMap而失败,c#,enums,mapping,automapper,automapper-10,C#,Enums,Mapping,Automapper,Automapper 10,应用程序是使用DDD方法构建的,带有一组单独的持久性模型。我称之为数据库对象或dbo: 公共类ParentDbo { public int ParentId{get;set;} 公共int类型ID{get;set;} } 公营儿童 { public int ChildId{get;set;} publicparentdbo Parent{get;set;} public int RetryNumber{get;set;} } 我们有一个简单的模型来研究:父母和孩子的关系。RetryNumber表

应用程序是使用DDD方法构建的,带有一组单独的持久性模型。我称之为数据库对象或dbo:

公共类ParentDbo { public int ParentId{get;set;} 公共int类型ID{get;set;} } 公营儿童 { public int ChildId{get;set;} publicparentdbo Parent{get;set;} public int RetryNumber{get;set;} } 我们有一个简单的模型来研究:父母和孩子的关系。RetryNumber表示数据库中的枚举值

在检索数据时,它首先使用Dapper查询数据库,然后使用splitOn功能将数据映射到数据库中。这一部分无关紧要,但为了完整起见,我还是要展示它:

常量字符串sql=从XXX中选择*。。。。; 使用var cnt=_dbConnectionFactory.CreateConnection { var childDbos=await cnt.QueryAsync sql:sql, 映射:childDbo,parentDbo=> { childDbo.Parent=parentDbo; 返回childbo; }, splitOn:ParentId ; } Dapper的局限性在于它无法将数据映射到私有复杂对象。这就是为什么我必须有两套模型的主要原因。我想用私有setter和其他技术将数据和逻辑封装在域模型中

以下是我的域模型:

公共类父类 { public int Id{get;private set;} public int TypeId{get;private set;} 公共Parentint parentId,int typeId { //验证 this.Id=parentId; this.TypeId=TypeId; } } 公营儿童 { public int Id{get;private set;} 公共父级{get;私有集;} 公共尝试{get;private set;} public Childint childId,父-父,尝试 { //验证 this.Id=childId; 这个。父=父; 这个。尝试=尝试; } } 对于域模型,我不需要公共setter和无参数构造函数

尝试是具有整数支持值的枚举:

公共枚举尝试 { 原始=1, FirstRetry=2, 第二次重试=3, LastRetry=4 } 最后,我想使用AutoMapper在Dbos和域模型之间进行映射。以下是映射:

公共类映射配置文件:配置文件 { 公共地图配置文件 { 创建地图 .ForMemberdest=>dest.ChildId,opts=>opts.MapFromsrc=>src.Id .ForMemberdest=>dest.RetryNumber,opts=>opts.MapFromsrc=>intsrc.trument .反向映射; 创建地图 .ForMemberdest=>dest.ParentId,opts=>opts.MapFromsrc=>src.Id .反向映射; } } 我想要两种方式的映射,所以我使用ReverseMap

.Net小提琴演示:

它将域模型映射到DBO,不会出现问题:

但反过来,从DBO到域模型的映射会引发异常:

未处理的异常。System.ArgumentException:程序+子级需要具有具有0个参数或仅具有可选参数的构造函数。参数“类型” 在lambda_Method18中,闭包、对象、子对象、ResolutionContext 在AutoMapper.Mapper.MapCore[TSource,TDestination]TSource source,TDestination destination,ResolutionContext context,键入sourceType,键入destinationType,IMemberMap memberMap 在AutoMapper.Mapper.Map[TSource,TDestination]TSource source,TDestination destination 在AutoMapper.Mapper.Map[TDestination]对象源 在Program.Main


我已尝试删除枚举属性,所有操作都正常,因此我非常确定是枚举映射出现问题。

据我在您的小提琴中看到,您正在尝试从ChildDbo映射到父对象,并且没有映射设置。将映射代码更改为:

var child2 = mapper.Map<Child>(childDbo);

或将第三个子项的ctor参数重命名为retryNumber:

或使用:


.

从ChildDbo到父母的地图是一个打字错误,但男人非常感谢你的帮助。我认为AutoMapper足够聪明,可以算出RetryNumber将映射到尝试,因为我在ReverseMap之前提供了映射。
CreateMap<Child, ChildDbo>()
    .ForMember(dest => dest.ChildId, opts => opts.MapFrom(src => src.Id))
    .ForMember(dest => dest.RetryNumber, opts => opts.MapFrom(src => (int)src.Attempt))
    .ReverseMap()
    .ConstructUsing((dbo, ctx) => new Child(dbo.ChildId, ctx.Mapper.Map<Parent>(dbo.Parent), (Attempt)dbo.RetryNumber));
public Child(int childId, Parent parent, Attempt retryNumber)
CreateMap<Child, ChildDbo>()
    .ForMember(dest => dest.ChildId, opts => opts.MapFrom(src => src.Id))
    .ForMember(dest => dest.RetryNumber, opts => opts.MapFrom(src => (int)src.Attempt))
    .ReverseMap()
    .ForCtorParam("attempt", opt => opt.MapFrom(dbo => dbo.RetryNumber))