Using AutoMapper to update Entity Framework properties

AutomapperEver found your self in need to auto map properties from one Entity Framework property to another (maybe even of the same type)?

Here’s an example of when you would need to do this. We just faced the need of receiving from a JSON service some data that matches the properties of an Entity, and the Service call is to update the Entity on the Database. So, from the Service we:

  1. Deserialize JSON string of data into an Entity object as defined by the Entity Framework .edmx’s .designer.cs classes file.
  2. We call our internal Entity Framework service to update that entity.

We know at this point that the Entity object we created at the service layer is a good entity, but won’t be easy to bind the entity into the DataContext of EntityFramework so that it knows to update the entity instead of adding a new one (and fail because of Unique Key indexing).

So what we want to do is:

  1. In the Entity Framework code, query the same Entity we are about to update from the DataContext. This will give us the Entity to update with valid context data (i.e. EntityKey).
  2. Map only the important/changed values from coming Entity into the one we just loaded from the DataContext.
  3. SaveChanges on the DataContext.

Problem is that if we use AutoMapper to do this, with it’s automatic configuration, it’ll simply try to map ALL properties (including context properties) and that’ll end up in several different errors like trying to set an NavigationPropertyReference property.

So, in the end, this is what we came up with:

We need to first configure AutoMapper to know how to map our entities:

AutoMapper.Mapper.CreateMap<EntityType, EntityType>()

.ForAllMembers(o => {

o.Condition(ctx =>

{

var members = ctx.Parent.SourceType.GetMember(ctx.MemberName); // get the MemberInfo that we are mapping

if (!members.Any())

return false;

return members.First().GetCustomAttributes(typeof(EdmScalarPropertyAttribute), false).Any(); // determine if the Member has the EdmScalar attribute set

});

});

This will tell the AutoMapper to ignore all non-scalar properties on the entity being mapped. That is, of course, what we usually want. If you needed to map Navigational Properties you’d have to work a whole lot of other magic to achieve this.

So in the end, you only need to configure this map for every single Entity you need to map to “itself” (to it’s same type) in order to automatically apply changes to DB Entities.

PS: I worked this out with Andres Meza, so kudos to Andres too!