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:
- 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".
- 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.