如何使用 AutoMapper 使用 EntityFramework 使用嵌套列表更新对象?

Posted

技术标签:

【中文标题】如何使用 AutoMapper 使用 EntityFramework 使用嵌套列表更新对象?【英文标题】:How to use AutoMapper for updating Object with nested List using EntityFramework? 【发布时间】:2022-01-03 15:40:44 【问题描述】:

我想使用 AutoMapper 将带有嵌套列表的 EntityDto 映射到实体,然后使用 SaveChanges() 调用对其进行更新。

问题在于 AutoMapper 将嵌套的 List 元素映射为新对象,因此 EntityFramework 认为我想添加具有现有 Id 的新对象。

例子:

    public class Entity
    
        public Guid Id  get; set; 
        public List<NestedEntity> NestedEntityList  get; set; 
    

    public class EntityDto
    
        public Guid Id  get; set; 
        public List<NestedEntityDto> NestedEntityList  get; set; 
    

    public class NestedEntity
    
        public Guid Id  get; set; 
        public string PropertyOne  get; set; 
        public string PropertyTwo  get; set; 
    

    public class NestedEntityDto
    
        public Guid Id  get; set; 
        public string PropertyTwo  get; set; 
    

例如,实体有一个包含 2 个 NestedEntity 对象的列表


    "Id": "EntityId"
    "NestedEntityList": [
        
            "Id": "A",
            "PropertyOne": "Value A",
            "PropertyTwo": "Value AA"
        ,
        
            "Id": "B",
            "PropertyOne": "Value B",
            "PropertyTwo": "Value BB"
        
    ]


更新:(A修改,B删除,C添加)

EntityDto 有一个包含 2 个 NestedEntity 对象的列表


    "Id": "EntityId"
    "NestedEntityList": [
        
            "Id": "A",
            "PropertyTwo": "Value AAA (Updated)"
        ,
        
            "Id": "C",
            "PropertyTwo": "Value CC"
        
    ]

无需进一步配置 AutoMapper 通过创建新对象来映射 NestedEntityList。这会导致两个问题:

    EntityFramework 会将这些新对象作为新创建的对象而不是已更新的现有对象进行跟踪。这会导致以下错误消息:“无法跟踪实体类型“NestedEntity”的实例,因为已经在跟踪另一个具有键值“A”的实例”。 如果NestedEntity 有PropertyOne 值,那么映射后为null,因为NestedEntityDto 没有PropertyOne。我想更新 EntityDto(即 PropertyTwo)中的属性并保留其他所有内容的值。

所以我想要达到的结果:(A修改,B删除,C添加)


    "Id": "EntityId"
    "NestedEntityList": [
        
            "Id": "A",
            "PropertyOne": "Value A", //Old value, not updated with NULL
            "PropertyTwo": "Value AAA (Updated)" //Updated value
        ,
        
            "Id": "C", //New item added in the update
            "PropertyOne": NULL,
            "PropertyTwo": "Value CC"
        
    ]

我需要如何配置 AutoMapper 来实现这一点?有可能吗?

【问题讨论】:

研究AutoMapper.Collection. 这解决了我的问题,谢谢。您应该写下您的评论作为答案,以便我接受。 【参考方案1】:

映射到现有集合时,首先清除目标集合。如果这不是您想要的,请查看AutoMapper.Collection。

【讨论】:

以上是关于如何使用 AutoMapper 使用 EntityFramework 使用嵌套列表更新对象?的主要内容,如果未能解决你的问题,请参考以下文章

3AutoMapper In Asp.net Core

C#console app与DB first Entity Framework和AutoMapper,无法将Model转换为DbModel

AutoMapper的使用

automapper在ORM中的作用,求教?

AutoMapper

如何在 .NetCore 中使用 AutoMapper 高级功能