在EF 6中更新子实体的正确方法是什么?

必须有一种更好的方法来处理EF 6中的子节省/更新。当然,这种重复只是我的失败。

实体

public partial class MyParentType { public MyParentType() { this.children = new HashSet(); } public int parentID { get; set; } public virtual ICollection children { get; set; } } 

添加/更新

 public class MyRepository : IMyRepository { private readonly IErrorLogger _logger; private readonly CorporateEntities _context; public MyRepository(IErrorLogger logger) { _logger = logger; _context = new CorporateEntities(); } public void Update(IEnumerable parents) { try { Add(parents.Where(x => x.parentID == 0)); var updatedData = parents.Where(x => x.parentID != 0); foreach (var parent in updatedData) { var original = _context.MyParentTypes.FirstOrDefault(x => x.parentID == parent.parentID); _context.Entry(original).CurrentValues.SetValues(parent); UpdateChildren(parent); } _context.SaveChanges(); } catch (Exception exception) { _logger.Error(exception.Message, exception); } } public void Add(IEnumerable parents) { if (parents == null) return; try { _context.MyParentTypes.AddRange(parents); _context.SaveChanges(); } catch (Exception exception) { _logger.Error(exception.Message, exception); } } private void UpdateChildren(MyParentType parent) { try { AddChildren(parent.children.Where(x => x.childID == 0)); var updatedData = parent.children.Where(x => x.childID != 0); foreach (var child in updatedData) { var original = _context.children.FirstOrDefault(x => x.childID == child.childID); _context.Entry(original).CurrentValues.SetValues(child); } _context.SaveChanges(); } catch (Exception exception) { _logger.Error(exception.Message, exception); } } private void AddChildren(IEnumerable references) { try { _context.children.AddRange(references); _context.SaveChanges(); } catch (Exception exception) { _logger.Error(exception.Message, exception); throw; } } } 

我觉得我不应该复制这个或写一个通用方法来处理这两种情况。 我是否遗漏了EF docuemtation中的哪些内容,我可以用父代实体更新子实体?

我建议你使用GraphDiff 。 使用此库,您的Update方法将如下所示:

  public void Update(IEnumerable parents) { try { Add(parents.Where(x => x.parentID == 0)); var updatedData = parents.Where(x => x.parentID != 0); foreach (var parent in updatedData) { _context.UpdateGraph(parent, map => map.OwnedCollection(p => p.children)); } _context.SaveChanges(); } catch (Exception exception) { _logger.Error(exception.Message, exception); } } 

这样您就不必担心管理孩子的状态了。

如果您不想使用GraphDiff,则需要手动管理子项的状态:

  public void Update(IEnumerable parents) { try { foreach (var parent in parents) { if(parent.Id==0) { _context.MyParentTypes.Add(parent); } else { //When you change the state to Modified all the scalar properties of the entity will be marked as modified _context.Entry(parent).State = EntityState.Modified; foreach(var child in parent.children) { context.Entry(child).State =child.Id>0? EntityState.Modified:EntityState.Added; } } } _context.SaveChanges(); } catch (Exception exception) { _logger.Error(exception.Message, exception); } }