C# 自动映射不更新嵌套集合

C# 自动映射不更新嵌套集合,c#,.net-core,automapper,webapi,C#,.net Core,Automapper,Webapi,我试图简化映射类的过程。为此,我使用AutoMapper。如果没有一个类没有嵌套的集合,那么一切都很好。但是如果有人这样做了,我在地图绘制方面就有麻烦了。正在覆盖类中的集合。我找到了分机。但这对我不起作用 我正在从事一个web api项目,因此这里的部分代码: // Classes for mapping public class A_Dto { public int Id { get; set; } public List<A_SubItem_Dto> SubIte

我试图简化映射类的过程。为此,我使用AutoMapper。如果没有一个类没有嵌套的集合,那么一切都很好。但是如果有人这样做了,我在地图绘制方面就有麻烦了。正在覆盖类中的集合。我找到了分机。但这对我不起作用

我正在从事一个web api项目,因此这里的部分代码:

// Classes for mapping
public class A_Dto
{
    public int Id { get; set; }
    public List<A_SubItem_Dto> SubItems { get; set; }

}

public class A_SubItem_Dto
{
    public int Id { get; set; }
    public string Value { get; set; }
    public A_Dto A_MainObject { get; set; }
}

public class A_Resource
{
    public int Id { get; set; }
    public List<A_SubItem_Resource> SubItems { get; set; }

}

public class A_SubItem_Resource
{
    public int Id { get; set; }
    public string Value { get; set; }
}

// Configure AutoMapper
public void ConfigureServices(IServiceCollection services)
{
    services.AddAutoMapper(cfg => cfg.AddCollectionMappers(), typeof(Startup));
}

// Configure profile class for mapping
public class AutoMapping : Profile
{
    CreateMap<A_Dto, A_Resource>().ReverseMap()
         .ForMember(m => m.Id, opt => opt.Ignore());
    CreateMap<A_SubItem_Dto, A_SubItem_Resource>().ReverseMap()
        .EqualityComparison((sir, si) => sir.Id == si.Id);
}

// Controller action with simple test
public async Task<IActionResult> Put(/*...*/)
{
    // Test
    var aDto = new A_Dto()
    {
        Id = 7,
        SubItems = new List<A_SubItem_Dto>() 
        { 
            new A_SubItem_Dto() { Id = 2, Value = "_2_" }, 
            new A_SubItem_Dto() { Id = 9, Value = "_9_" } 
        }
    };

    var aResource = new A_Resource()
    {
        Id = 7,
        SubItems = new List<A_SubItem_Resource>() 
        { 
            new A_SubItem_Resource() { Id = 2, Value = "_222222_" }
        }
    };

    _mapper.Map(aResource, aDto);
}
//用于映射的类
公共A级Dto
{
公共int Id{get;set;}
公共列表子项{get;set;}
}
公共A类\u子项\u Dto
{
公共int Id{get;set;}
公共字符串值{get;set;}
将数据公开给一个主对象{get;set;}
}
公共A类资源
{
公共int Id{get;set;}
公共列表子项{get;set;}
}
公共A类_子项_资源
{
公共int Id{get;set;}
公共字符串值{get;set;}
}
//配置自动映射器
public void配置服务(IServiceCollection服务)
{
services.AddAutoMapper(cfg=>cfg.AddCollectionMappers(),typeof(Startup));
}
//为映射配置配置文件类
公共类自动映射:配置文件
{
CreateMap().ReverseMap()
.ForMember(m=>m.Id,opt=>opt.Ignore());
CreateMap().ReverseMap()
.EqualityComparison((sir,si)=>sir.Id==si.Id);
}
//控制器动作与简单测试
公共异步任务Put(/*…*/)
{
//试验
var aDto=新的A_Dto()
{
Id=7,
子项=新列表()
{ 
新的A_子项_Dto(){Id=2,Value=“_2_”},
新的A_子项_Dto(){Id=9,Value=“_9_”}
}
};
var aResource=新的A_资源()
{
Id=7,
子项=新列表()
{ 
新的A_子项_资源(){Id=2,Value=“22222_2222}
}
};
_mapper.Map(aResource,aDto);
}
在结果中,
aDto
对象包含一个元素为
aResource.SubItems的新集合


您能告诉我,我做错了什么吗?

AutoMapper将不包括源集合中不存在的目标元素,这是默认行为。@Prolog,我不同意您的看法。如果打开AutoMapper.Collection的上述链接,您应该注意到“…将根据源集合和目标集合中集合的通用项类型之间的用户定义等效性,从先前存在的集合对象中添加/更新/删除项…”这是正确的。下面的几行也解释了从DTO集合映射到实体集合时映射的行为。“如果订单存在而OrderDTO不存在,则AutoMapper将从集合中删除订单”,这意味着“如果目标集合包含与源集合中的元素不匹配的元素,则这些元素将被删除。”而这正是id为
9
A\u子项\u Dto
的情况。它存在于目标集合中,但不存在于源集合中。它不匹配,因此被删除。请注意,源资源集合的元素少于目标DTO集合的元素。因此,AutoMapper映射的是两个元素之间匹配的单个元素,id
2
。我开始认为你在以错误的顺序传递变量。如果dto是某种用户输入数据,那么您应该从dto映射到实体。如果dto只是实体的视图模型,则从实体映射到dto,而不存在目标集合。