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:
.Ignore()
the Entity Key properties?.Attach()
my mapped Entity
and set the state to modified?Any help always appreciated.
.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);
}
}
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.