如何在父实体框架CF之前删除子实体?

qua*_*els 23 database entity-framework entity-framework-4.1

我试图使用EF代码优先删除数据库记录(deleteMe)和它的子(deleteMe.Prices).

foreach (var deleteMe in deleteThese)
{ 
   // Delete validation
   if(CanDeleteItem(deleteMe.ItemId))
   {
      db.Entry(deleteMe).State = EntityState.Deleted;

      foreach (var item in deleteMe.Prices)
      {
         db.Entry(item).State = EntityState.Deleted; // cascade delete
      }
   }
}
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

但是,实体框架似乎无法跟踪在父项之前应删除子记录的事实.我收到错误:

DELETE语句与REFERENCE约束"ItemPrice_Item"冲突.
冲突发生在数据库"DEVDB",表"dbo.ItemPrices",列'Item_ItemId'中.
该语句已终止.

我如何在EF中执行此删除?

qua*_*els 36

我最终找到了一条为我做的快速线:

foreach (var deleteMe in deleteThese)
{ 
   // Delete validation
   if(CanDeleteItem(deleteMe.ItemId))
   {
      ///
      deleteMe.Prices.ToList().ForEach(p => db.ItemPrices.Remove(p));
      ///

      db.Entry(deleteMe).State = EntityState.Deleted;
   }
}
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)


Eng*_*r T 11

EF6

context.Children.RemoveRange(parent.Children)
Run Code Online (Sandbox Code Playgroud)


Lad*_*nka 8

EF中的级联删除取决于数据库中关联配置的级联删除,因此如果您没有在数据库中配置级联删除,则必须先将所有项目价格加载到应用程序并将其标记为已删除.


Sve*_*ang 5

那么最简单的解决方案是首先迭代价格并调用保存更改,然后为deleteMe设置删除条目并再次调用保存更改,但是你检查了一下:实体框架代码首先用cascade删除吗?这似乎是你想要的.

好奇但也是为什么你只是不删除上下文中的实体来删除而是设置条目状态?

另一种选择是设置级联删除http://blogs.msdn.com/b/alexj/archive/2009/08/19/tip-33-how-cascade-delete-really-works-in-ef.aspx

做这样的事情(没有经过测试,但希望你得到了这个):

using (TransactionScope scope = new TransactionScope())
{    
    foreach (var deleteMe in deleteThese)
    { 
   // Delete validation
      if(CanDeleteItem(deleteMe.ItemId))
      {

         foreach (var item in deleteMe.Prices)
         {
            db.Entry(item).State = EntityState.Deleted; // cascade delete
         }
         db.SaveChanges();

         db.Entry(deleteMe).State = EntityState.Deleted;


     }
   }
   db.SaveChanges();
   scope.Complete();
}     
Run Code Online (Sandbox Code Playgroud)

另外你可以打电话:

db.Prices.Remove(item);
Run Code Online (Sandbox Code Playgroud)

db.DeleteMes.Remove(deleteMe);
Run Code Online (Sandbox Code Playgroud)

而不是设置进入状态.不确定两者之间的幕后是否存在差异.