Paul Aldred-Bann Paul Aldred-Bann - 2 months ago 101
C# Question

Mapping a DTO to an Entity with Automapper

I have an Entity Framework POCO with the following structure.

public class Entity
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}


I've created a Data Transfer Object for this entity to be used by my views.

public class EntityDto
{
public int Id { get; set; }
public string Name { get; set; }
}


Now, I have the following mapping code in my Global.asax file.

Mapper.CreateMap<Entity, EntityDto>();
Mapper.CreateMap<EntityDto, Entity>(); // not sure whether I need this as well?


Everything is working fine, I pass the DTO to my views OK and I can create a new instance of
Entity
from my
EntityDto
model. The problem arises when I try to edit my
Entity
; I'm aware this is down to AutoMapper losing the Entity Key that EF creates to track changes to the object, but having read through a few sources there doesn't seem to be a definitive solution. Here is the action I'm using to edit my entity.

public ActionResult EditEntity(EntityDto model)
{
var entity = context.Entities.Single(e => e.Id == model.Id);
entity = Mapper.Map<EntityDto, Entity>(model); // this loses the Entity Key stuff
context.SaveChanges();

return View(model);
}


Now, what do I do to solve this? Can I:


  1. Somehow tell AutoMapper to
    .Ignore()
    the Entity Key properties?

  2. Get AutoMapper to copy out the Entity Key properties?

  3. .Attach()
    my mapped
    Entity
    and set the state to modified?



Any help always appreciated.

Answer

.Attach() my mapped Entity and set the state to modified?

public ActionResult EditEntity(EntityDto model)
{
    var entity = Mapper.Map<Entity>(model);
    context.Set<Entity>().Attach(entity); // (or context.Entity.Attach(entity);)
    context.Entry<Entity>(entity).State = System.Data.EntityState.Modified;
    context.SaveChanges();
    return View(model);
}

Where is your context instanciated? You should do that in your EditEntity action imo.

public ActionResult EditEntity(EntityDto model)
{
    using(var context = new MyContext())
    {
        var entity = Mapper.Map<Entity>(model);
        context.Set<Entity>().Attach(entity); // (or context.Entity.Attach(entity);)
        context.Entry<Entity>(entity).State = System.Data.EntityState.Modified;
        context.SaveChanges();
        return View(model);
    }
}
Comments