我有以下表格结构。这两个表有20多个常见属性,我只列出了两个。我也有10张类似的表。这就是表在数据库中的方式。有超过10个具有相似属性的具体表格,并且不以任何方式相互连接。我正在使用POCO生成器从我的数据库生成类。
public class A
{
public string name {get;set;}
public string address {get;set;}
public string AId {get;set;}
}
public class B
{
public string name {get;set;}
public string address {get;set;}
public string BId {get;set;}
}
我有以下viewModels:
public class BaseViewModel
{
public string Fullname {get;set;}
public string Fulladdress {get;set;}
}
public class AviewModel : BaseViewModel
{
public string AId {get;set;}
}
public class BViewModel : BaseViewModel
{
public string BId {get;set;}
}
当我创建映射时,我必须为我创建的每个viewModel重复所有这些。
config.CreateMap<A, AviewModel>()
.ForMember(dest => Fulladdress, opt => opt.MapFrom(src =>.address))
.ForMember(dest => Fullname, opt => opt.MapFrom(src =>.name)).ReverseMap();
config.CreateMap<B, BviewModel>()
.ForMember(dest => Fulladdress, opt => opt.MapFrom(src =>.address))
.ForMember(dest => Fullname, opt => opt.MapFrom(src =>.name)).ReverseMap();
是否可以减少我可能需要做的重复映射?
答案 0 :(得分:2)
您需要源类的基类。您在基本源类和目标类之间创建一个映射。您可以在映射中将该映射包含在派生类中。这将允许您重用配置。 The docs。对于简单的情况,您可以使用As而不是Include。
答案 1 :(得分:2)
您可以将公共映射代码移动到辅助程序通用方法。您将TDestination
类型约束为派生自BaseViewModel
的类,从而允许以ForMember
方法访问目标成员。对于源映射,您将使用MapFrom
重载接受string
属性名称:
public static class CommonMappings
{
public static IMappingExpression<TSource, TDestination> MapToBaseViewModel<TSource, TDestination>(this IMappingExpression<TSource, TDestination> map)
where TDestination : BaseViewModel
{
return map
.ForMember(dest => dest.Fulladdress, opt => opt.MapFrom("address"))
.ForMember(dest => dest.Fullname, opt => opt.MapFrom("name"));
}
}
然后你可以像这样使用它:
config.CreateMap<A, AViewModel>()
.MapToBaseViewModel()
// ... specific mappings
.ReverseMap();
config.CreateMap<B, BViewModel>()
.MapToBaseViewModel()
// ... specific mappings
.ReverseMap();
更新:事实证明,此时最新的自动反向映射AutoMapper 6.1.1适用于MapFrom
的lambda重载,但不适用于string
过载(在AutoMapper 5中它根本不起作用)。因此,在修复之前,您可以使用以下MapFrom(string)
替换:
public static class AMExtensions
{
public static void From<TSource, TDestination, TMember>(this IMemberConfigurationExpression<TSource, TDestination, TMember> opt, string name)
{
var parameter = Expression.Parameter(typeof(TSource), "src");
var body = Expression.PropertyOrField(parameter, name);
var selector = Expression.Lambda(body, parameter);
opt.MapFrom((dynamic)selector);
}
}
这意味着您需要使用MapFrom
替换原始解决方案中的From
次来电,因为我们无法为扩展方法指定相同的名称,因为它的优先级低于具体的界面方法。
与基类方法相比,可能需要付出太多努力。但如果您无法控制实体类的设计,则非常有用。
答案 2 :(得分:0)
您在模型的属性上设置属性。 它包含它在源对象上映射的属性的名称。
然后创建一个接受目标对象和源对象的泛型方法,该方法在设置属性的属性上找到customattribute,在目标对象上找到属性(反之亦然),然后设置值。 / p>
您甚至可以通过询问是否为类属性来处理嵌套对象。