Joh*_*ohn 23 c# nested flatten automapper
我一直在将域对象展平为DTO,如下例所示:
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);
Run Code Online (Sandbox Code Playgroud)
我已经看了很多例子,到目前为止,这似乎是扁平嵌套层次结构的方法.但是,如果子对象具有许多属性,则此方法不会节省太多编码.
我找到了这个例子:
但它需要Map()函数所需的映射对象的实例,根据我的理解,它不适用于配置文件.
我是AutoMapper的新手,所以我想知道是否有更好的方法来做到这一点.
Jag*_*Jag 14
在最新版本的AutoMapper中,您可以使用命名约定来避免多个.ForMember语句.
在您的示例中,如果您将Flattened类更新为:
public class Flattened
{
public string AParentProperty { get; set; }
public string TheNestedClassANestedProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
您可以避免使用ForMember语句:
Mapper.CreateMap<Root, Flattened>();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Automapper将(根据惯例)映射Root.TheNestedClass.ANestedProperty到Flattened.TheNestedClassANestedProperty.当你使用真正的班级名字时,它看起来不那么难看,老实说!
Lee*_*des 13
我更喜欢避免使用旧的静态方法并这样做。
将我们的映射定义放入Profile 中。我们首先映射 Root,然后应用 Nested 的映射。注意Context的使用。
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Root, Flattened>()
.AfterMap((src, dest, context) => context.Mapper.Map(src.TheNestedClass, dest));
CreateMap<Nested, Flattened>();
}
}
Run Code Online (Sandbox Code Playgroud)
定义从Root到Flattened和Nested到Flatterned的映射的优点是您可以保留对属性映射的完全控制,例如目标属性名称是否不同或您想要应用转换等。
XUnit 测试:
[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);
}
Run Code Online (Sandbox Code Playgroud)
通过将 AutoMapper 的serviceCollection.AddAutoMapper()从AutoMapper.Extensions.Microsoft.DependencyInjection nuget 包添加到您的启动,配置文件将被自动选取,您可以简单地将IMapper注入到应用映射的任何位置。
2个可能的解决方案:
Mapper.CreateMap<Nested, Flattened>()
.ForMember(s=>s.AParentProperty, o=>o.Ignore());
Mapper.CreateMap<Root, Flattened>()
.ForMember(d => d.ANestedProperty, o => o.MapFrom(s => s.TheNestedClass));
Run Code Online (Sandbox Code Playgroud)
另一种方法如下,但它不会通过Mapper.AssertConfigurationIsValid().
Mapper.CreateMap<Nested, Flattened>()
//.ForMember map your properties here
Mapper.CreateMap<Root, Flattened>()
//.ForMember... map you properties here
.AfterMap((s, d) => Mapper.Map(s.TheNestedClass, d));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13582 次 |
| 最近记录: |