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 仍在查询执行前应用。
备注:内容仅供参考。
