Search code examples
c#entity-framework-coreautomapper

AutoMapper resets undefined parts(from source) in an already filled destination class's nested list element


Source

public class MaterialDto {
    public int MaterialId { get; set; }
    public List<MaterialLocaleDto> Locales{ get; set; }
}

public class MaterialLocaleDto {
    public int MaterialLocaleId { get; set; }
    public string MaterialLocaleText { get; set; }
}

Destination

public class MaterialEntity {
    public int MaterialId { get; set; }
    public List<MaterialLocaleEntity> Locales{ get; set; }
}

public class MaterialLocaleEntity {
    public int MaterialLocaleId { get; set; }
    public string MaterialLocaleText { get; set; }
    public int CriteriaId { get; set; } //Only different
}

I'm trying to update my entity in C# with EF Core and Automapper.

First I'm getting my destination object from db by source's id like this

MaterialEntity destObj = _contex.get(command.MaterialId);
/* Here my destObj as json to show what is inside
destObj = {
  "MaterialId": 1,
  "Locales": [
    {
      "MaterialLocaleId": 1,
      "MaterialLocaleText": "Some Text",
      "CriteriaId": 1
    },
    {
      "MaterialLocaleId": 2,
      "MaterialLocaleText": "Some other text",
      "CriteriaId": 1
    }
  ]
}
*/

And then I'm trying to map my source object which is come from ui.

_mapper.Map(MaterialDto,MaterialEntity);

But because of my (source) MaterialLocaleDto doesn't have CriteriaId definition set 0 in the destination. Final state of the destObj:

destObj = {
  "MaterialId": 1,
  "Locales": [
    {
      "MaterialLocaleId": 1,
      "MaterialLocaleText": "Some Text Came From Dto",
      "CriteriaId": 0 //I don't want to reset here 
    },
    {
      "MaterialLocaleId": 2,
      "MaterialLocaleText": "Some Other Text Came From Dto",
      "CriteriaId": 0 //I don't want to reset here 
    }
  ]
}

It works on the base object when I don't want to reset undeclared variables. But it resets on the nested list object.

Thanks for your help.


Solution

  • Automapper.Collection.EntityframeworkCore 9.0 Library solved my problem.

    When I adeded to program.cs to this code below:

    collection.AddAutoMapper(cfg => {
            cfg.AddCollectionMappers();
        }, typeof(MyProfile));
    

    And then managed my mappig profile like this:

    CreateMap<MaterialLocaleDto, MaterialLocaleEntity>().ReverseMap()
    .EqualityComparison((sir, si) => sir.MaterialLocaleId == si.MaterialLocaleId ); 
    

    Problems solved. Its just updating if there is a match with id. Or else creating. This is what exactly I want.