使用Automapper将DTO映射到实体

Pau*_*ann 8 c# entity-framework automapper

我有一个具有以下结构的实体框架POCO.

public class Entity
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我为这个实体创建了一个数据传输对象供我的视图使用.

public class EntityDto
{
    public int Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在,我在Global.asax文件中有以下映射代码.

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

一切正常,我将DTO传递给我的观点确定,我可以Entity从我的EntityDto模型中创建一个新实例.当我尝试编辑我的问题时出现问题Entity; 我知道这是由于AutoMapper失去了EF创建的跟踪对象更改的实体密钥,但是通过一些来源读取似乎并不是一个明确的解决方案.这是我用来编辑我的实体的动作.

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);
}
Run Code Online (Sandbox Code Playgroud)

现在,我该怎么做才能解决这个问题?我可以吗:

  1. 以某种方式告诉AutoMapper .Ignore()实体键属性?
  2. 获取AutoMapper以复制实体密钥属性?
  3. .Attach()我映射Entity并将状态设置为修改?

任何帮助总是赞赏.

dar*_*uby 15

尝试将实体作为第二个参数传递给您的映射.

entity = Mapper.Map<EntityDto, Entity>(model, entity);
Run Code Online (Sandbox Code Playgroud)

否则,您的实体实例将被新实例覆盖,并且您将丢失在第一行中创建的实体.

  • 神圣的 CRUD 我不知道你可以用 Map 做到这一点。惊人的。 (2认同)

Plu*_*luc 9

.Attach()我映射的实体并将状态设置为修改?

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);
}
Run Code Online (Sandbox Code Playgroud)

您的上下文在哪里实例化?你应该在EditEntity动作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);
    }
}
Run Code Online (Sandbox Code Playgroud)