如何使用AutoMapper更新具有嵌套实体的实体,并使用实体框架保存更新的实体?

时间:2017-01-25 20:36:30

标签: c# entity-framework automapper

我已经创建了一个映射,用于将ViewModel中的集合映射到Model上的另一个集合,该集合似乎没有问题。映射之后,Model的子对象具有适当的更新。

configuration.CreateMap<SourceViewModel, Destination>()                
            .ForMember(d => d.ChildOfDestination, 
                      opt => opt.MapFrom(s => Mapper.Map<ICollection<SourceViewModel>, ICollection<Destination>>(s.ChildOfSource)));

但是,在保存时会抛出错误:

  

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

我发现ChangeTracker.Entries()有额外的项目状态为“已添加”。例如,我的Model.ChildCollection的计数为2,但是在Entries()中,我有来自ChildCollection的原始2项,状态为“Modified”,而2个相同项目的状态为“Added”

public async Task<IHttpActionResult> Update([FromBody] SourceViewModel viewModel) {
    var model = await _repository.GetByIdAsync(viewModel.Id);
    Mapper.Map(viewModel, model);
    _repository.Update(model);
    await _unitOfWork.SaveAsync();
}

我写了一些代码来暂时解决这个问题,但是对于一个我不确定如何解决的更大问题是一个黑客攻击。

foreach (var child in ViewModel.Child)
{
  var record = Model.Child.SingleOrDefault(c => c.ID == child.ID);

  if (record != null)
      Mapper.Map(child, record);
  else
      Model.Child.Add(Mapper.Map<SourceViewModel, Destination>(child));
}

1 个答案:

答案 0 :(得分:1)

实体框架6

  

断开连接的数据是实体框架之前的一个老问题   就此而言,大多数数据访问工具。这从来都不是一件容易的事   一个要解决。服务器通过网络发送数据,不知道是什么   可能会在请求它的客户端应用程序中发生,甚至不知道   如果它会回来然后,突然,一些数据再次出现在请求中。   但这是相同的数据吗?在缺席的情况下该怎么办?难道   什么都发生了?这是全新的数据吗?非常担心   大约!

来源:https://msdn.microsoft.com/da-dk/magazine/mt694083

本网站上的一个非常好的回复,参考上面的文章:https://stackoverflow.com/a/21436713/550198

实体框架核心/实体框架7

实体框架核心(也称为EF7)具有允许您遍历对象图形的新功能。 e.g。

context.ChangeTracker.TrackGraph(someEntity,  e => e.Entry.State = EntityState.Added);