在实体框架MVC中更新子实体

时间:2014-07-16 20:20:36

标签: asp.net-mvc entity-framework

我在我的视图中显示父实体及其子项,并使用户能够编辑父实体和子实体。

当用户点击“保存”时。只有在忽略子实体时才会修改父实体。我的工作就是这个。

var addressRepo=_dataRepositoryFactory.GetDataRepository<IPatientAddressRepository>();
foreach (var address in entity.Addresses)
{
    addressRepo.Update(address);
}

_dataRepositoryFactory.GetDataRepository<IPatientContactRepository>().Update(entity.Contact);


var guardianRepo = _dataRepositoryFactory.GetDataRepository<IPatientGuardianRepository>();
foreach (var guardian in entity.Guardians)
{
    guardianRepo.Update(guardian);
}

_dataRepositoryFactory.GetDataRepository<IPatientDemographicRepository>().Update(entity.Demographic);

return _patientRepository.Update(entity);

是否有更好的方法来更新所有子实体?

2 个答案:

答案 0 :(得分:5)

对断开连接的实体应用更新时的标准模式如下:

  1. 将根实体附加到上下文以启用图表中的更改跟踪
  2. 这将整个对象图标记为EntityState.Unchanged,因此您需要走图表并按照惯例设置状态
  3. 将父实体标记为EntityState.Modified,以便其更改保持不变
  4. 对于每个子实体,计算更改的性质(插入,删除或更新)并相应地标记其状态
  5. 保存上下文后,图表中的更改将会保留。
  6. 采用这种方法意味着您可以将依赖性要求降低到根实体的单个存储库。

    例如,假设您只处理更新:

    using (var context = new MyContext())
    {
        context.attach(parentEntity);
        context.Entry(parentEntity).State = EntityState.Modified;
    
        context.Entity(parentEntity.ChildEntity1).State = EntityState.Modified;
        context.Entity(parentEntity.ChildEntity2).State = EntityState.Modidied;
    
        context.SaveChanges();
    }
    

    这通常被封装在您的存储库中的AttachAsModified方法中,该方法知道如何绘制状态&#34;基于图的根实体的对象图。

    E.g。

    public class MyRepository<TEntity>
    {
        public void AttachAsModified(TEntity entity)
        {
            _context.attach(entity);
            _context.Entry(entity).State = EntityState.Modifed;
            _context.Entity(entity.ChildEntity1).State = EntityState.Modified;
            // etc
            _context.SaveChanges();
        }   
    }
    

    如果您需要考虑子实体的插入或删除,则会有额外的复杂性。这些归结为加载根实体及其子实体的当前状态,然后将子集与更新的根实体上的集进行比较。然后根据集合的重叠将状态设置为EntityState.DeletedEntityState.Added

    NB代码直接输入浏览器,因此可能会/会有一些拼写错误。

答案 1 :(得分:2)

我记得在一次更新父母和孩子时遇到类似的问题。我并没有真正花时间弄清楚确切的原因,但我很快意识到,通过大量改变传回大量模型可能并不是最好的模型。在一个极端情况下,我的帖子非常大,超出了默认的邮件大小。

我更新像这样的大型父/子模型的首选方法是将整个父/子模型向下传递到页面,然后通过ajax单独更新每个子模型。因此,父和子永远不会在同一个动作中更新。它还使处理错误更容易,如果你传递一个庞大的模型并且一个孩子未通过验证,那么有时很难将这个错误以一种对用户来说显而易见的方式在集合等中传回。而进行单次更新对于用户来说更容易发现/处理。

我建议你使用View Models而不是直接将你的实体传递到你的视图中,除了最简单的视图之外,这被认为是不好的做法。您可以缩小模型以减少视图的有效负载,您还可以在将来轻松扩展视图模型以添加额外的功能,而不会影响您的实体。

只是一些想法,希望它有所帮助。