1

I am trying to update an entity using Entity Framework and save it to the database. When the update is called, my service method retrieves the DTO, assigns its the values of the entity object that the UI passed to it, and then saves it to the database. Instead of manually assigning those values, i'd like to use Automapper, however when I do this, the values that I am not mapping are updated to null. Is there a way in Entity Framework or Automapper to prevent this?

Service method finds the existing object in the database, assigns the new entity's properties to it, then saves:

public void Update(MyEntity updatedEntity, int id)
{
    var existingObject = db.tblmyentity.Find(id);

    existingObject.name = updatedEntity.name;
    existingObject.address = updatedEntity.address;
    existingObject.phone = updatedEntity.phone;

    db.SaveChanges();
}

However, there are values stored in fields of this object not accessible by the UI, such as who modified the object and when. Using AutoMapper to simplify this code (shown below) causes these fields to update to null:

public void Update(MyEntity updatedEntity, int id)
{
    var existingObject = db.tblmyentity.Find(id);

    Mapper.Map(updatedEntity, existingObject);

    db.SaveChanges();
}
johnny 5
  • 19,893
  • 50
  • 121
  • 195
Matt
  • 47
  • 1
  • 10
  • Take a look at this answer https://stackoverflow.com/questions/4987872/ignore-mapping-one-property-with-automapper – Bit May 18 '18 at 14:14
  • Possible duplicate of [Ignore mapping one property with Automapper](https://stackoverflow.com/questions/4987872/ignore-mapping-one-property-with-automapper) – Bit May 18 '18 at 14:15
  • 1
    Use a DTO only containing the properties to be modified. Or copy the values manually. I wouldn't use AM to implement business rules, or else business rules are scattered all over the place. – Gert Arnold May 18 '18 at 14:20
  • @Bit the problem is that they aren't the same properties needed to be ignored every time. This object has different properties updated on different UI pages. It would be nice to say "if the property that is going to be mapped is null, leave it alone and don't change it" – Matt May 18 '18 at 14:33
  • @Gert i'm assuming this is what you mean by business logic, which does suck to use scattered across at such a low level – Matt May 18 '18 at 14:33
  • Yes, and more, because sometime you do want to save values that are set to null. A DTO is the best guarantee that you show/save what you actually want to show/save. With AM it's too easy to overlook newly added properties in the entity that should be ignored. That's a common mistake. – Gert Arnold May 18 '18 at 14:41
  • @Matt In that case I would not use Automapper but move to a DTO as others have pointed out. – Bit May 18 '18 at 14:43

1 Answers1

1

A good practice is to create a (service, api) model that contains only the relevant properties that can be updated. E.g.:

public class MyEntityServiceModel
{
    public string name { get; set; }
    public string address { get; set; }
    public string phone { get; set; }
}

// this looks differently in recent versions of AutoMapper, but you get the idea
Mapper.CreateMap<MyEntityServiceModel, MyEntity>();

// your update functions looks the same, except that it receives a service model, not a data model

Update(MyEntityServiceModel updatedEntity, int id) 
{
   // same code here
}

This approach has the following advantages:

  • you obtain what you are asking for
  • safety: you do not risk updating more properties than you should since the service model clearly specify the properties that should be updated
  • serialization: the service model is more appropriate if you need serialization (EF models may include unwanted navigation properties)
  • Update function consumer becomes unaware of the data persistence library you are using.
Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164