0

我的数据库中的两个表 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 视为链接表。

上面的外键没有级联删除,我也没有设置任何东西来处理实体框架外键关联上的 OnDelete。然而,当我从代码中删除一个用户实体时,实体框架冒昧地删除了用户 ID 与其关联的用户产品。它还生成大量 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 从来没有这样做过:您必须在代码中手动加载然后删除所有相关实体。

谢谢

4

2 回答 2

1

实体框架默认有一个

OneToManyCascadeDelete

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

所以实体框架级联默认删除一对多关系。

您可以通过禁用约定来禁用它,或者通过 fluent API 为这种关系显式禁用它。

于 2014-09-11T17:16:25.600 回答
0

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

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

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

于 2014-09-16T08:11:17.010 回答