2011-05-25 88 views
5

我有一些错误: EF 4: Removing child object from collection does not delete it - why?EF 4.1:从集合中删除子对象不会删除它 - 为什么?

当我删除,当我打电话SaveChanges()孩子被删除父一子,它给出了如下错误信息:

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

但是对于DbContext和EF 4.1,“context.DeleteObject(recipe)”不存在。

有什么建议吗?

[编辑]

public void UpdateWithAttributes(Model model, IEnumerable<Entity> entities) 
    { 
     var modelOriginal = this.unitOfWork.Model.GetById(model.IModel); 

     this.unitOfWork.Context.Entry(modelOriginal).CurrentValues.SetValues(model); 
     UpdateEntityAttributeAssociations(modelOriginal, entities); 

     this.unitOfWork.Commit(); 
    } 

    public void UpdateEntityAttributeAssociations(Model model, IEnumerable<Entity> current) 
    { 
     unitOfWork.Context.Entry(model).Collection(m => m.Entities).Load(); 
ICollection<Entity> original = model.Entities; // perhaps .ToList() necessary 

     // delete 
     if (original != null) 
     { 
      List<Entity> toDelete = GetToDelete(original, current); 

      foreach (Entity originalEntityToDelete in toDelete) 
      { 
       unitOfWork.Context.Entity.Remove(originalEntityToDelete); 
      } 
     } 

     // add, update 
     if (current != null) 
     { 
      foreach (Entity currentEntity in current) 
      { 
       // No need to set the UpdatedWhen. The trigger on the table will handle that. 
       if (original.Where(originalEntity => originalEntity.IEntity == currentEntity.IEntity).FirstOrDefault() == null) 
       { 
        model.Entities.Add(currentEntity); 
       } 
      } 
     } 
    } 

回答

1

我想你再次添加你刚才删除的内容,因为从DbSet中删除也会从子集合original内部删除该实体。然后在第二个循环中再次添加实体。你可以尝试赶上这种情况下,像这样:

public void UpdateEntityAttributeAssociations(Model model, 
               IEnumerable<Entity> current) 
{ 
    unitOfWork.Context.Entry(model).Collection(m => m.Entities).Load(); 
    ICollection<Entity> original = model.Entities; // perhaps .ToList() necessary 

    // delete 
    List<Entity> toDelete = null; 
    if (original != null) 
    { 
     toDelete = GetToDelete(original, current); 
     foreach (Entity originalEntityToDelete in toDelete) 
     { 
      unitOfWork.Context.Entity.Remove(originalEntityToDelete); 
     } 
    } 

    // add, update 
    if (current != null) 
    { 
     foreach (Entity currentEntity in current) 
     { 
      if (toDelete == null || !toDelete.Contains(currentEntity)) 
      { 
       if (original.Where(originalEntity => originalEntity.IEntity == 
           currentEntity.IEntity).FirstOrDefault() == null) 
       { 
        model.Entity.Add(currentEntity); 
       } 
      } 
     } 
    } 
} 

我还更换了你的第一行以明确装载子集,因为你的程序来查询子实体人工看起来生疏了,但我不认为这是问题(但我不知道)。

编辑

我不知道如果我上面的代码有助于消除你有例外。我不知道如果将实体添加到已处于Deleted状态的集合,并且这可能会引发此异常,会发生什么情况。

如果代码无法帮助您测试是否还存在没有第二个(插入)循环的问题。以及GetToDelete究竟如何?以及如何看待你的ModelEntity类和他们的关系?并且model.Entity的确是另一个集合,而不是model.Entities(或者它是一个错字)?

+0

感谢Slauma对你的响应使用你的代码我有另一个错误:DELETE语句与REFERENCE约束{0}发生冲突冲突发生在数据库\“MyDatabase \”,表\“{1} \”中,列'{2}'。\ r \ n声明已被终止。 – rad 2011-05-25 17:57:21

+0

@rad:我不知道你应该编辑我最后一个问题的答案。有太多的缺失信息来详细了解问题并提供一个工作解决方案(至少对我而言)。 – Slauma 2011-05-25 18:05:01

+0

@rad:我认为还有另一个实体指的是你刚刚试图删除的实体。 “{0}”,“{1}”和“{2}”的秘密内容应该给出一个相当重要的提示! – Slauma 2011-05-25 18:14:01

2

你要拨打:

context.Recipes.Remove(recipe); 

RecipesDbSet<Recipe>

+0

我试过,但我还是同样的错误:( – rad 2011-05-25 15:10:23

+0

更新的代码示例你的问题。 – 2011-05-25 15:13:02

+0

它的更新,谢谢 – rad 2011-05-25 16:04:46