PAYATHON 2026

AutoMapper 如何将导航集合映射为字符串列表?

数据小陈

结论

AutoMapper 可以完成映射,无需手动遍历。将 DTO 中的 ProductAttributes 定义为 List<string>,并在 Product 到 ProductDto 的映射配置中选取每个元素的 Attribute 属性。

配置 DTO 和映射

public class ProductDto
{
    public int Id { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public List<string> ProductAttributes { get; set; }
}

CreateMap<Product, ProductDto>()
    .ForMember(
        dest => dest.ProductAttributes,
        opt => opt.MapFrom(src => src.ProductAttributes.Select(a => a.Attribute)));

MapFrom 会将每个 ProductAttribute 转换为对应的 Attribute 字符串,因此多个有效属性会作为多个元素保留在列表中。

如果沿用先查询实体、再映射 DTO 的流程,可以在 ToListAsync() 后调用:

var productsList = await products.ToListAsync();
var result = mapper.Map<List<ProductDto>>(productsList);
return result;

输出会类似 "productAttributes": ["new"]。

在 EF Core 查询中投影

如果要直接从数据库查询并生成 DTO,可以使用 AutoMapper 的 ProjectTo,并将它作为查询的最后一个投影操作:

var result = await products
    .ProjectTo<ProductDto>(mapper.ConfigurationProvider)
    .ToListAsync();

return result;

这种方式要求 EF Core 查询提供程序能够翻译映射表达式。上面的属性选择属于简单投影;如果映射中包含无法翻译的自定义方法,应先调用 ToListAsync(),再使用 mapper.Map。

使用 ProjectTo 时,通常无需单独调用 Include 来填充 DTO,投影会根据映射表达式选择所需数据。具体的 SQL 翻译能力取决于映射配置和查询提供程序。

注意事项

如果 ProductAttributes 可能为 null,应将源集合初始化为空集合,或在映射表达式中处理空值,以避免空引用。分页和排序应作用于预期的数据集。采用投影时,确认 OrderBy、Skip 和 Take 仍在查询执行前应用。

备注:内容仅供参考。