Home > Back-end >  How to use AutoMapper for updating Object with nested List using EntityFramework?
How to use AutoMapper for updating Object with nested List using EntityFramework?

Time:11-26

I would like to use AutoMapper for mapping a EntityDto with nested List to the Entity, then update it with a SaveChanges() call.

The problem is that AutoMapper maps nested List elements as new objects, so EntityFramework thinks I want to add new objects with already existing Ids.

Example:

    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; }
    }

Entity has for example a list that contains 2 NestedEntity objects

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

Update: (A modified, B deleted, C added)

EntityDto has a list that contains 2 NestedEntity objects

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

Without further configuration AutoMapper maps NestedEntityList by creating new objects. This results in 2 problems:

  1. EntityFramework will track these new objects as freshly created objects instead of existing objects that were updated. This results in the following error message: "The instance of entity type "NestedEntity" cannot be tracked because another instance with the key value "A" is already being tracked".
  2. If NestedEntity has a PropertyOne value, then after the mapping, it will be null, because NestedEntityDto does not have PropertyOne. I want to update the properties in the EntityDto (which is PropertyTwo) and keep the value of everything else.

So the result that I would like to achieve: (A modified, B deleted, C added)

{
    "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"
        }
    ]
}

How do I need to configure AutoMapper to achieve this? Is it possible at all?

CodePudding user response:

When mapping to an existing collection, the destination collection is cleared first. If this is not what you want, take a look at AutoMapper.Collection.

  • Related