EF 4.1多对多删除父母应该删除相关的孩子

时间:2012-02-08 21:06:57

标签: entity-framework entity-framework-4 entity-framework-4.1 ef-code-first

EF 4.1数据库第一种方法。

说我有这个表架构

  

用户1 --- M UserRoles M --- 1角色

在外键中设置级联删除

UserRoles表还有其他列,如CreatedDate,因此我为UserRoles创建了一个模型并相应地进行映射。

我最终得到以下模型:

User
----
int Id
string Name
List<UserRoles> UserRoles

UserRoles
---------
int UserId
int RoleId
DateTime CreatedDate
User User
Role Role

Role
----
int Id
string Name
List<UserRoles> UserRoles

如果我的配置正确,我是否应该删除用户并删除用户角色行而不必手动清除UserRoles集合?

我可以这样做:

DbContext.Entry(user).State = EntityState.Deleted;
DbContext.SaveChanges();

或者我必须这样做:

user.UserRoles.Clear();
DbContext.Entry(user).State = EntityState.Deleted;
DbContext.SaveChanges();

我的测试显示我必须清除子集合,但我发现有相互矛盾的信息,如果我正确地进行了级联删除设置,它应该只删除用户。

当我不清除UserRoles时,我收到此错误:

  

因为一个或多个关系无法改变   外键属性是不可为空的

感谢您帮助澄清这一点!

2 个答案:

答案 0 :(得分:3)

您必须使用

DbContext.Users.Remove(user);

将状态设置为Deleted与此不同。设置状态不会将任何具有级联删除设置的子对象标记为Deleted,但Remove会这样做。

将状态设置为Deleted应该工作 IF 没有子项被加载到上下文中,因为EF只会将父项的DELETE语句发送到数据库,数据库将删除子项以及由于数据库中的级联删除。

IF 但是您已将子项加载到上下文设置中,Deleted的父项上的状态将不会设置子项的状态。 EF会抛出异常,而不是抱怨的数据库。

答案 1 :(得分:1)

您应该能够指定删除角色或用户将依次删除子授权。您可以在流畅的DbModelBuilder API上使用WillCascadeOnDelete()方法:

modelBuilder.Entity<UserRoles>
    .HasRequired(d => d.User)
    .WithMany(p => p.UserRoles)
    .HasForeignKey(d => d.UserId)
    .WillCascadeOnDelete();

modelBuilder.Entity<Role>
    .HasMany(p => p.UserRoles)
    .WithRequired(d => d.Role)
    .HasForeignKey(d => d.RoleId)
    .WillCascadeOnDelete();

使用此设置,删除用户或角色也应删除所有UserRoles。