我正在尝试在域对象和viewmodel之间创建一个映射,以支持一种非常常见的用例。我无法找到解决方案的事实让我觉得我正在接近这个问题。这是一些代表我的源和目标类型的伪代码:
public class DomainClass
{
public NestedDomainClass1 NestedDomainClass1{ get; set; }
}
public class NestedDomainClass1
{
public NestedDomainClass2 NestedDomainClass2 { get; set; }
}
public class NestedDomainClass2
{
public string PropertyA { get; set; }
public string PropertyB { get; set; }
public string PropertyC { get; set; }
}
public class DomainViewModel
{
public string PropertyA { get; set; }
public string PropertyB { get; set; }
public string PropertyC { get; set; }
}
如您所见,DomainViewModel
完美映射到DomainClass.NestedDomainClass1.NestedDomainClass2
。但是,由于不完全相关的原因,我不能简单地在该级别创建映射。相反,我必须将两个级别映射得更高:
Mapper.CreateMap<DomainObj, DomainViewModel>();
这很不幸,因为一旦我这样做,我就不能再依赖AutoMapper约定来自动映射类似命名的属性了,我最终不得不编写大量高度重复的代码:
Mapper.CreateMap<DomainClass, DomainViewModel>().ForMember(dest=>dest.PropertyA, opt=>opt.MapFrom(source=>source.NestedDomainClass1.NestedDomainClass2.PropertyA));
Mapper.CreateMap<DomainClass, DomainViewModel>().ForMember(dest=>dest.PropertyB, opt=>opt.MapFrom(source=>source.NestedDomainClass1.NestedDomainClass2.PropertyB));
我使用了RecognizeDestinationPrefixes
和RecognizeDestinationPostfixes
方法,希望让AutoMapper直接“跳过”我要映射的属性(NestedDomainClass2
),但没有运气。任何帮助将不胜感激!
答案 0 :(得分:0)
那是因为你在两种完全不同的类型之间尝试映射。你真的需要做这样的事情:
Mapper.CreateMap<NestedDomainClass2, DomainViewModel>();
Mapper.AssertConfigurationIsValid();
var dvm = Mapper.Map<NestedDomainClass2, DomainViewModel>
(obj.NestedDomainClass1.NestedDomainClass2);
但是,如果您愿意,可以通过定义TypeConverter
隐藏该详细信息。这样的事情应该有效:
public class DomainTypeConverter : TypeConverter<DomainClass, DomainViewModel>
{
protected override DomainViewModel ConvertCore(DomainClass source)
{
return Mapper.Map<NestedDomainClass2, DomainViewModel>
(source.NestedDomainClass1.NestedDomainClass2);
}
}
然后,您可以将映射定义为:
Mapper.CreateMap<NestedDomainClass2, DomainViewModel>();
Mapper.CreateMap<DomainClass, DomainViewModel>()
.ConvertUsing(new DomainTypeConverter());
Mapper.AssertConfigurationIsValid();
并像这样使用它:
var dvm = Mapper.Map<DomainClass, DomainViewModel>(dc);