需要映射成员和构造函数的自动映射器

编程入门 行业动态 更新时间:2024-10-22 19:29:46
本文介绍了需要映射成员和构造函数的自动映射器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我是AutoMapper的新手,我只是想找出做事情的最佳方式。

我很快就遇到了两个简单但真实的对象模型之间的映射问题。第一个用于服务层:

public sealed class GeoLocation { public GeoLocation( double latitude, double longitude) { this.Latitude = latitude; this.Longitude = longitude; } public double Latitude { get; private set; } public double Longitude { get; private set; } } public sealed class Location { public Location( string name, GeoLocation geoLocation) { this.Name = name; this.GeoLocation = geoLocation; } public string Name { get; private set; } public GeoLocation GeoLocation { get; private set; } }

第二个是上述数据库层的简化表示:

public sealed class LocationEntity { public LocationEntity( string name, double latitude, double longitude) { this.Name = name; this.Latitude = latitude; this.Longitude = longitude; } public string Name { get; } public double Latitude { get; } public double Longitude { get; } }

如果我尝试使用简单的CreateMap<Location, LocationEntity>().ReverseMap()调用来映射类型,则可以预见在验证映射时会出现问题:

AutoMapperConfigurationException: Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters =============================================== Location -> LocationEntity (Destination member list) UserQuery+Location -> UserQuery+LocationEntity (Destination member list) No available constructor. =============================================== LocationEntity -> Location (Destination member list) UserQuery+LocationEntity -> UserQuery+Location (Destination member list) Unmapped properties: GeoLocation No available constructor.

很公平。我不想映射每个构造函数参数,所以我尝试调用ConstructUsing:

Mapper.Initialize( config => { config .CreateMap<Location, LocationEntity>() .ConstructUsing((source, _) => new LocationEntity(source.Name, source.GeoLocation?.Latitude ?? 0.0, source.GeoLocation?.Longitude ?? 0)); config .CreateMap<LocationEntity, Location>() .ConstructUsing((source, _) => new Location(source.Name, new GeoLocation(source.Latitude, source.Longitude))); });

但是,这仍然抱怨LocationEntity->Location映射:

AutoMapperConfigurationException: Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters =============================================== LocationEntity -> Location (Destination member list) UserQuery+LocationEntity -> UserQuery+Location (Destination member list) Unmapped properties: GeoLocation

不确定还能做什么,我添加了对LocationEntity->Location映射的ForMember调用:

config .CreateMap<LocationEntity, Location>() .ConstructUsing((source, _) => new Location(source.Name, new GeoLocation(source.Latitude, source.Longitude))) .ForMember( x => x.GeoLocation, options => options.MapFrom((source, target, _, context) => new GeoLocation(source.Latitude, source.Longitude))); 虽然这解决了问题,但在我看来,我的映射已经变得有些复杂了。我在想:有没有更好的方法来做这件事,而不牺牲我的对象模型的设计?

推荐答案

您的对象模型设计基本上只允许通过构造进行映射(转换),因此无法充分利用AutoMapper自动和显式映射功能。

ConstructUsing用于选择用于创建目标实例的非默认构造函数,但仍需要成员映射。

您需要的是ConvertUsing方法:

跳过成员映射并使用自定义表达式转换为目标类型

Mapper.Initialize(config => { config.CreateMap<Location, LocationEntity>() .ConvertUsing(source => new LocationEntity(source.Name, source.GeoLocation?.Latitude ?? 0.0, source.GeoLocation?.Longitude ?? 0)); config.CreateMap<LocationEntity, Location>() .ConvertUsing(source => new Location(source.Name, new GeoLocation(source.Latitude, source.Longitude))); });

更多推荐

需要映射成员和构造函数的自动映射器

本文发布于:2023-11-16 11:48:09,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1604006.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   成员   映射器

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!