使用 AutoMapper 展平嵌套对象的更好方法?

时间:2023-01-05
本文介绍了使用 AutoMapper 展平嵌套对象的更好方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我已经将域对象扁平化为 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>();
    }
}

同时定义从 RootFlattenedNestedFlatterned 的映射的优点是您可以保留完全控制属性的映射,例如目标属性名称是否不同或您想要应用转换等.

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 展平嵌套对象的更好方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:如何让 XMLSerializer 向嵌套对象中的属性添加命名空间? 下一篇:在 VS 2008 嵌套 Masterpage 中包含对 JavaScript 的相对引用的首选方法

相关文章

最新文章