You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Automapper通过ID映射非关联属性的实现方法

实现AutoMapper从InitialDeviceLocation映射DeviceName和LocationName的方案

咱们一步步来搞定这个需求:你的InitialDeviceLocation实体只存了DeviceId和LocationId,现在要通过这两个ID关联查询出对应的名称,映射到目标DTO里。下面是具体实现步骤:

1. 定义目标DTO

先创建一个包含所需属性的DTO类,新增DeviceName和LocationName字段:

public class InitialDeviceLocationDto
{
    public int Id { get; set; }
    public Guid CampaignId { get; set; }
    public int DeviceId { get; set; }
    public int LocationId { get; set; }
    // 需要新增的名称属性
    public string DeviceName { get; set; }
    public string LocationName { get; set; }
}

2. 准备查询名称的服务/仓储

你需要能通过ID获取设备、位置名称的服务,先定义两个接口:

public interface IDeviceRepository
{
    Task<string> GetDeviceNameByIdAsync(int deviceId);
    // 其他仓储方法按需添加
}

public interface ILocationRepository
{
    Task<string> GetLocationNameByIdAsync(int locationId);
    // 其他仓储方法按需添加
}

然后实现这两个接口,比如用EF Core查询Device和Location实体的Name属性(具体实现根据你的数据库结构调整即可)。

3. 配置AutoMapper Profile

创建AutoMapper配置类,通过构造函数注入上面的仓储,在映射规则里指定如何获取名称:

public class MappingProfile : Profile
{
    private readonly IDeviceRepository _deviceRepo;
    private readonly ILocationRepository _locationRepo;

    // 注入仓储服务
    public MappingProfile(IDeviceRepository deviceRepo, ILocationRepository locationRepo)
    {
        _deviceRepo = deviceRepo;
        _locationRepo = locationRepo;

        CreateMap<InitialDeviceLocation, InitialDeviceLocationDto>()
            // 基础属性自动映射,无需额外配置
            .ForMember(dest => dest.DeviceName, opt => opt.ResolveUsing(async src => 
                await _deviceRepo.GetDeviceNameByIdAsync(src.DeviceId)))
            .ForMember(dest => dest.LocationName, opt => opt.ResolveUsing(async src => 
                await _locationRepo.GetLocationNameByIdAsync(src.LocationId)));
    }
}

4. 注册服务到DI容器

在Startup.cs(.NET 6+用Program.cs)里注册AutoMapper、仓储及实现类:

// .NET 3.x/5 Startup.cs示例
public void ConfigureServices(IServiceCollection services)
{
    // 注册仓储
    services.AddScoped<IDeviceRepository, DeviceRepository>();
    services.AddScoped<ILocationRepository, LocationRepository>();

    // 注册AutoMapper,指定配置类所在程序集
    services.AddAutoMapper(typeof(MappingProfile));

    // 其他必要服务注册(比如DbContext、Controllers)
    services.AddDbContext<YourDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    services.AddControllers();
}

// .NET 6+ Program.cs示例
builder.Services.AddScoped<IDeviceRepository, DeviceRepository>();
builder.Services.AddScoped<ILocationRepository, LocationRepository>();
builder.Services.AddAutoMapper(typeof(MappingProfile));
// 其他配置...

5. 在业务逻辑中使用映射器

在Controller或业务服务中注入IMapper,执行异步映射:

[ApiController]
[Route("api/[controller]")]
public class InitialDeviceLocationsController : ControllerBase
{
    private readonly IMapper _mapper;
    private readonly YourDbContext _context;

    public InitialDeviceLocationsController(IMapper mapper, YourDbContext context)
    {
        _mapper = mapper;
        _context = context;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<InitialDeviceLocationDto>>> GetAll()
    {
        var entities = await _context.InitialDeviceLocations.ToListAsync();
        // 异步映射实体到DTO
        var dtos = await _mapper.MapAsync<IEnumerable<InitialDeviceLocationDto>>(entities);
        return Ok(dtos);
    }
}

可选优化:用AutoMapper投影直接查询数据库

如果想避免先查实体再映射的开销,可以用ProjectTo直接在数据库层面完成投影,性能更优:
修改MappingProfile(无需注入仓储,前提是DbContext包含Devices和Locations集合):

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<InitialDeviceLocation, InitialDeviceLocationDto>()
            .ForMember(dest => dest.DeviceName, opt => opt.MapFrom(src => 
                _context.Devices.FirstOrDefault(d => d.Id == src.DeviceId).Name))
            .ForMember(dest => dest.LocationName, opt => opt.MapFrom(src => 
                _context.Locations.FirstOrDefault(l => l.Id == src.LocationId).Name));
    }
}

查询时直接用ProjectTo:

[HttpGet]
public async Task<ActionResult<IEnumerable<InitialDeviceLocationDto>>> GetAll()
{
    var dtos = await _context.InitialDeviceLocations
        .ProjectTo<InitialDeviceLocationDto>(_mapper.ConfigurationProvider)
        .ToListAsync();
    return Ok(dtos);
}

内容的提问来源于stack exchange,提问作者TDC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:39:07