AutoMapper 中的复杂对象条件映射

问题描述 投票:0回答:1

这是我的目标对象和嵌套对象

public class Category
{
    public int Id { get; set; }
    public string CategoryName { get; set; }
    public string CategorryDescription { get; set; }
    public List<Product> ProductList { get; set; }
}

public class Product
{
    public  int Id { get; set; }
    public string ProductName { get; set; }
    public string ProductDescription { get; set; }
    public int CategoryId { get; set; }

    public Category Category { get; set; }
}

这是我的源对象和嵌套对象

public class CategoryUpdateDTO
{
    public int Id { get; set; }
    public string? CategoryName { get; set; }
    public string CategorryDescription { get; set; }
    public List<ProductUpdateDTO> ProductList { get; set; }
}

public class ProductUpdateDTO
{
    public int Id { get; set; }
    public string ProductName { get; set; }
    public int CategoryId { get; set; }
    public string ProductDescription { get; set; }
}

这是我的地图档案

public MapProfile()
{

    CreateMap<Category, CategoryCreateDTO>().ReverseMap();
    CreateMap<Product, ProductCreateDTO>().ReverseMap();
    CreateMap<Category, CategoryUpdateDTO>();
    CreateMap<CategoryUpdateDTO, Category>();
    CreateMap<Product, ProductUpdateDTO>();
    CreateMap<ProductUpdateDTO, Product>();
    CreateMap<Category, CategoryDTO>().ReverseMap();
    CreateMap<Product, ProductDTO>().ReverseMap();
}

这是我的服务代码

var category = await _myContext.Categories.Include(x => x.ProductList).Where(x => x.Id == categoryUpdateDTO.Id).FirstOrDefaultAsync();

category = _mapper.Map<CategoryUpdateDTO, Category>(categoryUpdateDTO, category);

我的问题

在进行此匹配时,我应该怎么做才能将 ProductUpdate 列表和 Pruduct 列表与相同的 Id 列进行匹配? 不是 我想这样做是因为 我希望更改跟踪器能够准确跟踪实体状态。

c# .net entity-framework-core automapper
1个回答
0
投票

我建议在映射时忽略此属性

CreateMap<Category, CategoryUpdateDTO>()
    .ReverseMap()
    .ForPath(x => x.ProductList, x => x.Ignore());

获取扩展方法,这是我为这种情况编写的CollectionHelpers。 添加额外的方法,适用于

Automapper

public class CollectionHelpers 
{
    public static void MergeCollections<TDestination, TSource, TDestinationKey>(
        DbContext context,
        ICollection<TDestination> destination,
        ICollection<TSource> source,
        Func<TDestination, TDestinationKey> destinationKeyFunc,
        Func<TSource, TDestinationKey> sourceKeyFunc,
        IMapper mapper)
        where TDestinationKey : notnull
    {
        MergeCollections(destination, source, destinationKeyFunc, sourceKeyFunc, 
            s => mapper.Map<TSource, TDestination>(s), 
            (d, s) => mapper.Map<TSource, TDestination>(s, d), 
            d => context.Remove(d));
    }

    // other overloads
}

那么您的更新应该如下所示:

var category = await _myContext.Categories
    .Include(x => x.ProductList)
    .Where(x => x.Id == categoryUpdateDTO.Id)
    .FirstOrDefaultAsync();

if (category != null)
{
    _mapper.Map<CategoryUpdateDTO, Category>(categoryUpdateDTO, category);

    CollectionHelpers.MergeCollections(_myContext, 
        category.ProductList, 
        categoryUpdateDTO.ProductList, 
        x => x.Id, 
        x => x.Id, 
        _mapper);
}
© www.soinside.com 2019 - 2024. All rights reserved.