在C#项目里,当需要将一个对象的属性值复制到另一个对象时,如果手动逐个赋值会非常繁琐,AutoMapper就是专门解决这类对象映射问题的工具。它支持自动匹配同名字段,也提供了丰富的配置能力应对复杂场景。

AutoMapper基础使用回顾
首先需要在项目中安装AutoMapper包,通过NuGet安装AutoMapper和AutoMapper.Extensions.Microsoft.DependencyInjection即可。基础使用需要先定义映射配置,再通过IMapper实例执行映射。
先定义两个测试实体类:
// 源实体
public class UserSource
{
public int Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public DateTime CreateTime { get; set; }
}
// 目标实体
public class UserDestination
{
public int Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string CreateTimeStr { get; set; }
}
基础的映射配置如下:
// 定义映射配置类
public class UserProfile : Profile
{
public UserProfile()
{
// 基础映射,自动匹配同名字段
CreateMap<UserSource, UserDestination>();
}
}
// 注册服务(在Program.cs中)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAutoMapper(typeof(UserProfile));
var app = builder.Build();
// 使用映射
public class UserService
{
private readonly IMapper _mapper;
public UserService(IMapper mapper)
{
_mapper = mapper;
}
public UserDestination GetUserDestination(UserSource source)
{
return _mapper.Map<UserDestination>(source);
}
}
进阶配置:自定义字段映射
当源实体和目标实体的字段名不一致时,可以通过ForMember方法自定义映射规则,比如上面的CreateTime是DateTime类型,目标实体中CreateTimeStr是字符串类型,需要转换格式:
public class UserProfile : Profile
{
public UserProfile()
{
CreateMap<UserSource, UserDestination>()
// 自定义CreateTimeStr的映射规则,将CreateTime转换为yyyy-MM-dd格式的字符串
.ForMember(dest => dest.CreateTimeStr,
opt => opt.MapFrom(src => src.CreateTime.ToString("yyyy-MM-dd")));
}
}
进阶配置:条件映射
有时候我们只在满足特定条件时才映射某个字段,可以使用Condition方法设置映射条件:
public class UserProfile : Profile
{
public UserProfile()
{
CreateMap<UserSource, UserDestination>()
.ForMember(dest => dest.Email,
opt => {
// 只有当源实体的Email不为空时才映射
opt.Condition(src => !string.IsNullOrEmpty(src.Email));
opt.MapFrom(src => src.Email);
});
}
}
进阶配置:自定义值解析器
如果某个字段的映射逻辑比较复杂,或者多个映射配置中都会用到相同的逻辑,可以自定义值解析器。首先定义解析器类实现IValueResolver接口:
// 自定义值解析器,将用户状态转换为对应的描述
public class UserStatusResolver : IValueResolver<UserSource, UserDestination, string>
{
public string Resolve(UserSource source, UserDestination destination, string destMember, ResolutionContext context)
{
// 假设UserSource中有Status字段,1代表启用,0代表禁用
return source.Status == 1 ? "启用" : "禁用";
}
}
// 源实体增加Status字段
public class UserSource
{
public int Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public DateTime CreateTime { get; set; }
public int Status { get; set; }
}
// 目标实体增加StatusDesc字段
public class UserDestination
{
public int Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string CreateTimeStr { get; set; }
public string StatusDesc { get; set; }
}
在映射配置中使用自定义解析器:
public class UserProfile : Profile
{
public UserProfile()
{
CreateMap<UserSource, UserDestination>()
.ForMember(dest => dest.StatusDesc,
opt => opt.MapFrom<UserStatusResolver>());
}
}
进阶配置:映射前后操作
如果需要在映射执行前后做一些额外操作,可以使用BeforeMap和AfterMap方法:
public class UserProfile : Profile
{
public UserProfile()
{
CreateMap<UserSource, UserDestination>()
// 映射前操作,比如给源实体补充默认值
.BeforeMap((src, dest) =>
{
if (string.IsNullOrEmpty(src.UserName))
{
src.UserName = "默认用户";
}
})
// 映射后操作,比如给目标实体赋值额外字段
.AfterMap((src, dest) =>
{
dest.CreateTimeStr = src.CreateTime.ToString("yyyy年MM月dd日");
});
}
}
进阶配置:集合映射与反向映射
AutoMapper默认支持集合的映射,不需要额外配置,同时可以通过ReverseMap开启反向映射:
public class UserProfile : Profile
{
public UserProfile()
{
// 开启反向映射,支持从UserDestination映射到UserSource
CreateMap<UserSource, UserDestination>().ReverseMap();
}
}
// 集合映射示例
public List<UserDestination> GetUserDestinationList(List<UserSource> sourceList)
{
return _mapper.Map<List<UserDestination>>(sourceList);
}
// 反向映射示例
public UserSource GetUserSource(UserDestination destination)
{
return _mapper.Map<UserSource>(destination);
}
注意事项
- 映射配置只需要定义一次,不需要重复创建,建议按照模块拆分不同的Profile类,便于维护
- 尽量避免在映射逻辑中写过于复杂的业务代码,保持映射的单一职责
- 可以通过
AssertConfigurationIsValid方法在启动时校验映射配置是否正确,避免运行时出错
// 在Program.cs中启动时校验配置
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var mapper = scope.ServiceProvider.GetRequiredService<IMapper>();
mapper.ConfigurationProvider.AssertConfigurationIsValid();
}
AutoMapperC#对象映射映射配置修改时间:2026-07-12 21:27:16