实体框架级联删除,即使在数据库中没有设置CASCADE

时间:2014-06-18 02:00:42

标签: entity-framework-6.1

我的数据库中的两个表UserProducts和Users之间存在外键关系,UserProducts的UserID引用了Users表中的UserID。

ALTER TABLE [dbo].[UserProducts]  WITH CHECK ADD  CONSTRAINT [FK_UserProducts_Users] FOREIGN KEY ([UserID])
REFERENCES [dbo].[Users] ([UserID])
GO

ALTER TABLE [dbo].[UserProducts] CHECK CONSTRAINT [FK_UserProducts_Users]
GO

UserProducts表中的UserID列是具有另一列ProductID的复合主键的一部分。还有两个额外的DateTime列,因此Entity Framework不会将UserProducts视为链接表。

上面的外键没有级联删除,也没有在Entity Framework外键关联上设置任何处理OnDelete的东西。然而,当我从代码中删除User实体时,Entity Framework可以自由删除UserID与之关联的UserProducts。它还会生成大量SQL:UserProducts表中的每个相关记录都有一个单独的DELETE。

执行实体删除的代码如下:

using (var context = new LicensingRegistrationContext(_csb))
{
    context.Database.Log = a => _logger.Trace(a);

    var dbUser = GetUserDbSetWithIncludes(context)
        .Where(a => a.UserID == user.Id).Single();

    context.DbUsers.Remove(dbUser);

    //TODO(MRL): Um...how are the dbUserProducts being removed???

    context.SaveChanges();
}

这是怎么回事?在EF 4中,我非常确定EF从未采取这种做法:您必须在代码中手动加载然后删除所有相关实体。

由于

2 个答案:

答案 0 :(得分:1)

默认情况下,实体框架有

OneToManyCascadeDelete

约定。这是链接http://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.conventions.onetomanycascadedeleteconvention(v=vs.113).aspx

因此,实体框架级联默认删除一对多关系。

您可以通过禁用约定来禁用此功能,或通过Fluent API为此关系显式禁用它。

答案 1 :(得分:0)

我在MSDN找到了这个,我相信这就是发生的事情:

  

当主体实体的主键也是从属实体的主键的一部分时,该关系是识别关系。在识别关系中,没有主体实体,依赖实体不能存在。此约束在标识关系中导致以下行为:删除主体对象也会删除依赖对象。这与在关系模型中指定OnDelete Action =“Cascade”的行为相同。删除关系会删除依赖对象。在EntityCollection上调用Remove方法标记关系和要删除的依赖对象。

这是我的模型中发生的事情,其中​​UserComponent表具有复合主键:UserID,ComponentID和UserID列是User表中UserID的外键。