问题描述
我已经将域对象扁平化为 DTO,如下例所示:
I have been flattening domain objects into DTOs as shown in the example below:
public class Root
{
public string AParentProperty { get; set; }
public Nested TheNestedClass { get; set; }
}
public class Nested
{
public string ANestedProperty { get; set; }
}
public class Flattened
{
public string AParentProperty { get; set; }
public string ANestedProperty { get; set; }
}
// I put the equivalent of the following in a profile, configured at application start
// as suggested by others:
Mapper.CreateMap<Root, Flattened>()
.ForMember
(
dest => dest.ANestedProperty
, opt => opt.MapFrom(src => src.TheNestedClass.ANestedProperty)
);
// This is in my controller:
Flattened myFlattened = Mapper.Map<Root, Flattened>(myRoot);
我查看了许多示例,到目前为止,这似乎是展平嵌套层次结构的方法.但是,如果子对象具有多个属性,则此方法不会节省太多编码.
I have looked at a number of examples, and so far this seems to be the way to flatten a nested hierarchy. If the child object has a number of properties, however, this approach doesn't save much coding.
我找到了这个例子:
http://consultingblogs.emc.com/owainwragg/archive/2010/12/22/automapper-mapping-from-multiple-objects.aspx
但它需要映射对象的实例,这是 Map() 函数所需的,根据我的理解,它不适用于配置文件.
but it requires instances of the mapped objects, required by the Map() function, which won't work with a profile as I understand it.
我是 AutoMapper 的新手,所以我想知道是否有更好的方法来做到这一点.
I am new to AutoMapper, so I would like to know if there is a better way to do this.
推荐答案
我更喜欢避免使用旧的静态方法并这样做.
I much prefer avoiding the older Static methods and do it like this.
将我们的映射定义放入配置文件.我们首先映射 Root,然后应用 Nested 的映射.请注意 Context 的使用.
Place our mapping definitions into a Profile. We map the Root first, and then apply the mappings of the Nested afterwards. Note the use of the Context.
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Root, Flattened>()
.AfterMap((src, dest, context) => context.Mapper.Map(src.TheNestedClass, dest));
CreateMap<Nested, Flattened>();
}
}
同时定义从 Root 到 Flattened 和 Nested 到 Flatterned 的映射的优点是您可以保留完全控制属性的映射,例如目标属性名称是否不同或您想要应用转换等.
The advantage of defining both the mapping from Root to Flattened and Nested to Flatterned is that you retain full control over the mapping of the properties, such as if the destination property name is different or you want to apply a transformation etc.
一个 XUnit 测试:
An XUnit test:
[Fact]
public void Mapping_root_to_flattened_should_include_nested_properties()
{
// ARRANGE
var myRoot = new Root
{
AParentProperty = "my AParentProperty",
TheNestedClass = new Nested
{
ANestedProperty = "my ANestedProperty"
}
};
// Manually create the mapper using the Profile
var mapper = new MapperConfiguration(cfg => cfg.AddProfile(new MappingProfile())).CreateMapper();
// ACT
var myFlattened = mapper.Map<Root, Flattened>(myRoot);
// ASSERT
Assert.Equal(myRoot.AParentProperty, myFlattened.AParentProperty);
Assert.Equal(myRoot.TheNestedClass.ANestedProperty, myFlattened.ANestedProperty);
}
通过将 AutoMapper.Extensions.Microsoft.DependencyInjection nuget 包中的 AutoMapper 的 serviceCollection.AddAutoMapper() 添加到您的启动中,将自动获取配置文件,并且您可以简单地将 IMapper 注入到您应用映射的任何位置.
By adding AutoMapper's serviceCollection.AddAutoMapper() from the AutoMapper.Extensions.Microsoft.DependencyInjection nuget package to your start up, the Profile will be picked up automatically, and you can simply inject IMapper into wherever you are applying the mapping.
这篇关于使用 AutoMapper 展平嵌套对象的更好方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!