Skip to content

对象到对象映射

将对象映射到另一个对象是常用并且繁琐重复的工作,大部分情况下两个类都具有相同或相似的属性. ABP 提供了对象到对象映射的抽象并集成了AutoMapper做为对象映射器.

AutoMapper 集成

AutoMapper 是最流行的对象到对象映射库之一. Volo.Abp.AutoMapper程序包使用 AutoMapper 实现了 IObjectMapper.

定义映射

AutoMapper 提供了多种定义类之间映射的方法. 有关详细信息请参阅AutoMapper 的文档.

其中定义一种映射的方法是创建一个Profile 类. 例如:

C#
1
2
3
4
5
6
7
public class MyProfile : Profile
{
    public MyProfile()
    {
        CreateMap<User, UserDto>();
    }
}

然后使用AbpAutoMapperOptions注册配置文件:

C#
[DependsOn(typeof(AbpAutoMapperModule))]
public class MyModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        Configure<AbpAutoMapperOptions>(options =>
        {
            //Add all mappings defined in the assembly of the MyModule class
            options.AddMaps<MyModule>();
        });
    }
}

AddMaps 注册给定类的程序集中所有的配置类,通常使用模块类. 它还会注册 attribute 映射.

配置验证

AddMaps 使用可选的 bool 参数控制模块配置验证:

C#
options.AddMaps<MyModule>(validate: true);

如果此选项默认是 false , 但最佳实践建议启用. 可以使用 AddProfile 而不是 AddMaps 来控制每个配置文件类的配置验证:

C#
options.AddProfile<MyProfile>(validate: true);

如果你有多个配置文件,并且只需要为其中几个启用验证,那么首先使用AddMaps而不进行验证,然后为你想要验证的每个配置文件使用AddProfile.

映射对象扩展

对象扩展系统 允许为已存在的类定义额外属性. ABP 框架提供了一个映射定义扩展可以正确的映射两个对象的额外属性.

C#
1
2
3
4
5
6
7
8
public class MyProfile : Profile
{
    public MyProfile()
    {
        CreateMap<User, UserDto>()
            .MapExtraProperties();
    }
}

如果两个类都是可扩展对象(实现了 IHasExtraProperties 接口),建议使用 MapExtraProperties 方法. 更多信息请参阅对象扩展文档.

其他有用的扩展方法

有一些扩展方法可以简化映射代码.

忽视审计属性

当你将一个对象映射到另一个对象时,通常会忽略审核属性.

假设你需要将 ProductDto (DTO)映射到 Product实体,该实体是从 AuditedEntity 类继承的(该类提供了 CreationTime, CreatorId, IHasModificationTime 等属性).

从 DTO 映射时你可能想忽略这些基本属性,可以使用 IgnoreAuditedObjectPropertie() 方法忽略所有审计属性(而不是手动逐个忽略它们):

C#
1
2
3
4
5
6
7
8
public class MyProfile : Profile
{
    public MyProfile()
    {
        CreateMap<ProductDto, Product>()
            .IgnoreAuditedObjectProperties();
    }
}

还有更多扩展方法, 如 IgnoreFullAuditedObjectProperties()IgnoreCreationAuditedObjectProperties(),你可以根据实体类型使用.

请参阅实体文档中的"基类和接口的审计属性"部分了解有关审计属性的更多信息。

忽视其他属性

在 AutoMapper 中,通常可以编写这样的映射代码来忽略属性:

C#
1
2
3
4
5
6
7
8
public class MyProfile : Profile
{
    public MyProfile()
    {
        CreateMap<SimpleClass1, SimpleClass2>()
            .ForMember(x => x.CreationTime, map => map.Ignore());
    }
}

我们发现它的长度是不必要的并且创建了 Ignore() 扩展方法:

C#
1
2
3
4
5
6
7
8
public class MyProfile : Profile
{
    public MyProfile()
    {
        CreateMap<SimpleClass1, SimpleClass2>()
            .Ignore(x => x.CreationTime);
    }
}

使用

C#
1
2
3
4
5
6
// 注入IObjectMapper
public virtual async Task<LanguageDto> GetAsync(string cultureName)
{
    var entity = await _languageRepository.FindAsync(cultureName);
    return ObjectMapper.Map<Language, LanguageDto>(entity);
}