Mapping a DTO to an Entity with Automapper

automapper c# entity-framework

Question

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.

1
9
10/31/2012 11:04:36 AM

Accepted 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 instantiated? 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);
    }
}
10
4/3/2017 11:57:03 AM

Popular Answer

Try passing entity as a second parameter to your mapping.

entity = Mapper.Map<EntityDto, Entity>(model, entity);

Otherwise, your entity instance is overwritten with a new instance, and you lose the entity created in the first line.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow