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

如何映射同类型列表属性?Category与CategoryDto映射场景

如何映射同类型的列表属性(比如嵌套分类列表)

嘿,我来帮你搞定这个同类型列表的映射问题!你需要把Category实体里的嵌套子分类列表(还有关联的产品列表)映射到对应的CategoryDto对吧?下面我会用两种实际项目里常用的方案来讲解,不管是小项目手动控制,还是中大型项目用工具简化代码都能覆盖到。

一、手动映射(适合小项目或需要精细控制的场景)

首先得补全你的CategoryDto(我默认你需要对应的嵌套子分类和产品列表属性,要是有调整你可以按需修改):

public class CategoryDto { 
    public Guid Id { get; set; } 
    public string CategoryName { get; set; } 
    public Guid? ParentCategoryId { get; set; } 
    public int? Level { get; set; } 
    // 对应原始类的ChildrenCategory
    public IList<CategoryDto> ChildrenCategoryDto { get; } = new List<CategoryDto>(); 
    // 对应原始类的Products,假设你有配套的ProductDto
    public IList<ProductDto> ProductsDto { get; } = new List<ProductDto>(); 
}

// 配套的ProductDto示例
public class ProductDto {
    public Guid Id { get; set; }
    public string ProductName { get; set; }
    // 其他产品属性按需添加
}

因为是同类型的递归列表(子分类还是Category类型),我们需要写个递归的映射方法来处理整个嵌套树:

public static class CategoryMapper
{
    // 单个Category转CategoryDto
    public static CategoryDto MapToDto(Category category)
    {
        if (category == null) return null;

        var dto = new CategoryDto
        {
            Id = category.Id,
            CategoryName = category.CategoryName,
            ParentCategoryId = category.ParentCategoryId,
            Level = category.Level
        };

        // 递归映射子分类列表:每个子Category都转成CategoryDto
        foreach (var child in category.ChildrenCategory)
        {
            dto.ChildrenCategoryDto.Add(MapToDto(child));
        }

        // 顺便处理Products列表到ProductDto的映射
        foreach (var product in category.Products)
        {
            dto.ProductsDto.Add(MapProductToDto(product));
        }

        return dto;
    }

    // 批量映射:把Category列表转成CategoryDto列表
    public static List<CategoryDto> MapToDtoList(IList<Category> categories)
    {
        return categories?.Select(MapToDto).ToList() ?? new List<CategoryDto>();
    }

    // 辅助方法:Product转ProductDto
    private static ProductDto MapProductToDto(Product product)
    {
        if (product == null) return null;

        return new ProductDto
        {
            Id = product.Id,
            ProductName = product.ProductName
        };
    }
}

这里的核心逻辑就是递归调用映射方法处理子分类,这样不管你的分类树有多少层,都能完整映射到Dto的嵌套列表里。

二、使用AutoMapper(适合中大型项目,减少重复代码)

如果你的项目比较大,手动写映射会很繁琐,AutoMapper这个工具能帮你自动处理递归映射,只需要配置一次规则就行。

步骤1:安装AutoMapper

通过NuGet包管理器安装:

Install-Package AutoMapper
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

步骤2:配置映射规则

创建一个映射配置类,告诉AutoMapper怎么把实体转成Dto:

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        // 配置Category到CategoryDto的映射
        CreateMap<Category, CategoryDto>()
            // 显式指定子分类列表的映射(AutoMapper能自动识别递归,但显式写更清晰)
            .ForMember(dest => dest.ChildrenCategoryDto, opt => opt.MapFrom(src => src.ChildrenCategory))
            // 配置Products到ProductsDto的映射
            .ForMember(dest => dest.ProductsDto, opt => opt.MapFrom(src => src.Products));

        // 配置Product到ProductDto的映射
        CreateMap<Product, ProductDto>();
    }
}

步骤3:注册AutoMapper到依赖注入(ASP.NET Core项目)

在Program.cs里把AutoMapper加入服务容器:

builder.Services.AddAutoMapper(typeof(MappingProfile));

步骤4:实际使用映射

在需要的地方注入IMapper接口,直接调用映射方法就行:

public class CategoryService
{
    private readonly IMapper _mapper;

    // 构造函数注入IMapper
    public CategoryService(IMapper mapper)
    {
        _mapper = mapper;
    }

    public CategoryDto GetCategoryById(Guid id)
    {
        // 假设从数据库获取Category实体
        var category = FetchCategoryFromDatabase(id);

        // 单个实体转Dto
        var categoryDto = _mapper.Map<CategoryDto>(category);

        // 如果是列表的话,直接转列表
        // var categoryDtos = _mapper.Map<List<CategoryDto>>(categoryList);

        return categoryDto;
    }

    // 模拟数据库查询方法
    private Category FetchCategoryFromDatabase(Guid id)
    {
        // 这里写你的实际查询逻辑
        return new Category();
    }
}

AutoMapper会自动识别递归关系,处理子分类列表的时候会自动复用已经配置好的Category到CategoryDto的规则,完全不用你手动写递归,非常省心!

小提示

  • 如果你的Dto列表属性名称和实体的名称完全一致(比如实体是ChildrenCategory,Dto也是ChildrenCategory),那AutoMapper可以自动匹配,不需要写ForMember配置。
  • 手动映射的时候一定要注意空值判断,避免出现NullReferenceException,比如先检查category是否为null再处理。
  • 要是分类嵌套层级特别深,手动映射可能会有一点点性能开销,但一般业务场景下分类层级不会超过5层,所以基本没影响;AutoMapper内部做了优化,递归映射的表现很稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:03:45