【问题标题】:EF 4.1 Many to Many Delete Parent should delete related childrenEF 4.1 多对多删除父级应删除相关子级
【发布时间】:2012-02-08 21:06:56
【问题描述】:

EF 4.1 数据库优先方法。

假设我有这个表架构

用户 1---M 用户角色 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 时,我收到此错误:

无法更改关系,因为其中一项或多项 外键属性不可为空

感谢您帮助澄清这一点!

【问题讨论】:

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


    【解决方案1】:

    你必须使用

    DbContext.Users.Remove(user);
    

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

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

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

    【讨论】:

    • 谢谢!我以为我快疯了……是的,孩子们已经满载而归,这就解释了为什么这没有按预期工作。他们(EF 团队)应该改变这种行为......似乎不是很直观
    【解决方案2】:

    您应该能够指定删除角色或用户将依次删除子授权。您可以在流畅的 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();
    

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

    【讨论】:

    • 当您说“应该”时,您的意思是您有可以执行此操作的代码吗?
    • 是的,我们的模型与您的非常相似,只是我们将 UserRole 称为“Grant”实体,并且我们不会在其上公开外键属性。此外,您必须确保所有导航和集合属性在 POCO 中都标记为虚拟。尽管我们没有任何删除角色的代码,但我们确实有删除用户的代码,并且由于WillCascadeOnDelete,它会级联到授权。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 2021-12-02
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多