映射一个DTO与Automapper实体(Mapping a DTO to an Entity wi

2019-07-03 11:59发布

我有一个实体框架POCO结构如下。

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

我创建了一个数据传输对象为受我的意见可以使用该实体。

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

现在,我在Global.asax文件下面的映射代码。

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

一切工作正常,我通过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);
}

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

  1. 不知怎的告诉AutoMapper到.Ignore()实体键的属性?
  2. 获得AutoMapper复制了实体键的属性?
  3. .Attach()我的映射Entity和设置状态来修改?

任何帮助总是赞赏。

Answer 1:

.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);
}

哪里是你的上下文中实例? 你应该做的是在你的EditEntity行动海事组织。

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);
    }
}


Answer 2:

尝试通过实体作为第二个参数的映射。

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

否则,你的实体实例是覆盖一个新实例,你失去了在第一行创建的实体。



Answer 3:

不需要Automapper的DTO到实体转换的备选答案是使用DbEntry:

        var oldEntity = DbSet.FirstOrDefault(x => x.Id == updatedEntity.Id);
        var oldEntry = Context.Entry(oldEntity);

        oldEntry.CurrentValues.SetValues(updatedEntity);

你不需要任何附加/状态检查,因为你是第一个让老实体,以便它已经更改跟踪连接到它。 此外,CurrentValues.SetValues可以接受不同类型的,在该示例updatedEntity是DTO。 设置值文档解释这样的:

通过读取值超出给定对象的设置此字典的值。 给定的对象可以是任何类型的。 在对象上的任何财产与在字典相匹配的属性名称,可以读出一个名字将被读取。 其他属性将被忽略。 这允许,例如,从简单的数据传输对象(DTO的)属性的复制。

所以看起来它已经可以在automapper式的方式进行。



文章来源: Mapping a DTO to an Entity with Automapper