简体   繁体   English

如何使用Entity Framework 6在具有多个外键的实体上应用级联删除?

[英]How to apply cascade delete on entities which have several foreign keys with Entity Framework 6?

I have the two entities below: 我有以下两个实体:

[Table("TimeZone")]
public class TimeZone
{
    [Required]
    [Column("Name"), Index("IX_Name", IsUnique = true)]
    [StringLength(50)]
    public string Name { get; set; }

    [Column("Description")]
    [StringLength(100)]
    public string Description { get; set; }

    [Column("IANAID"), Index("IX_IANAID", IsUnique = true)]
    [StringLength(50)]
    public string IANAId { get; set; }

    public ICollection<ApplicationUser> Users { get; set; }

    public TimeZone()
    {
        Users = new HashSet<ApplicationUser>();
    }
}

[Table("User")]
public class ApplicationUser : IdentityUser<string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>
{ 
    // [...]

    [Column("TimeZoneID"), ForeignKey("TimeZone")]
    public string TimeZoneId { get; set; }
    [Column("RegionID"), ForeignKey("Region")]
    public string RegionId { get; set; }
    [Column("ManagerID"), ForeignKey("Manager")]
    public string ManagerId { get; set; }

    // One-to-One
    public virtual TimeZone TimeZone { get; set; }

    // One-to-One
    public virtual Region Region { get; set; }

    // One-to-Many
    public virtual ApplicationUser Manager { get; set; }

    // One-to-many
    public virtual ICollection<Appointment> Appointments { get; set; }

    // Many-to-many
    public virtual ICollection<OnCallGroup> OnCallGroups { get; set; }

    // One-to-many
    public virtual ICollection<ApplicationUser> Subordinates { get; set; }
}

When I delete a record from TimeZone table which is used in the User table, the related records should be deleted according to the Cascadde Delete convention. 当我从User表中使用的TimeZone表中删除一条记录TimeZone ,应根据Cascadde Delete约定删除相关记录。

However since there are other foreign keys, I get the following exception with Entity Framework: 但是,由于还有其他外键,我在实体框架中遇到以下异常:

The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.User_dbo.TimeZone_TimeZoneID". DELETE语句与REFERENCE约束“ FK_dbo.User_dbo.TimeZone_TimeZoneID”冲突。 The conflict occurred in database "APPLICATIONDB_753c3d2ad2634cbf8cb62b098cdc6043", table "dbo.User", column 'TimeZoneID'. 在数据库“ APPLICATIONDB_753c3d2ad2634cbf8cb62b098cdc6043”的表“ dbo.User”的“ TimeZoneID”列中发生了冲突。 The statement has been terminated. 该语句已终止。

Is it normal that even though there is the cascade delete enabled by default on EF6 Code First, deleting a record from TimeZone does not delete all the related users? 即使默认情况下在EF6 Code First上启用了级联删除,从TimeZone中删除记录不会删除所有相关用户,这是否正常?

Note: In my ApplicationDbContext I overrided the OnModelCreating method: 注意:在我的ApplicationDbContext中,我重写了OnModelCreating方法:

    protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
    {
        base.OnModelCreating(dbModelBuilder);

        dbModelBuilder.Conventions.Add<OneToManyCascadeDeleteConvention>();
        dbModelBuilder.Conventions.Add<ManyToManyCascadeDeleteConvention>();
        dbModelBuilder.Conventions.Remove<PluralizingTableNameConvention>();


        // [...]
    }

The FK property ( TimeZoneId ) CLR type is string , which allows null , and no [Required] attribute has been applied to the FK or navigation property, thus making the relationship optional , ie ApplicationUser may exist without TimeZone . FK属性( TimeZoneId )CLR类型为string ,允许为null ,并且没有[Required]属性已应用于FK或Navigation属性,因此使该关系成为可选关系,即ApplicationUser可能不存在TimeZone And by default convention EF does not turn cascade delete on optional relationships. 并且默认情况下,EF不会对可选关系启用级联删除。

To turn the cascade delete on, you need either to make the relationship required by applying the [Required] attribute on either TimeZoneId or TimeZone property, or use fluent API in case you need to keep it optional by adding the following inside OnModelCreating override: 要打开级联删除,您需要通过在TimeZoneIdTimeZone属性上应用[Required]属性来建立所需的关系,或者使用fluent API,以防您需要在OnModelCreating覆盖内添加以下内容来保持可选OnModelCreating

modelBuilder.Entity<TimeZone>()
    .HasMany(e => e.Users)
    .WithOptional(e => e.TimeZone)
    .HasForeignKey(e => e.TimeZoneId)
    .WillCascadeOnDelete(); // <--

The same applies to other relationships using string FK properties. 使用string FK属性的其他关系也是如此。

Update: Actually the second option is not really an option. 更新:实际上,第二个选项实际上不是一个选项。 Even if it sets cascade delete on, EF treats cascade delete on optional relationships differently - when principal entity is deleted, it disassociates the related records by setting FKs to null rather than deleting them. 即使将级联删除设置为打开,EF也会以不同的方式对待可选关系上的级联删除-删除主体实体时,它通过将FK设置为null而不是删除它们来取消关联记录。 So you really have to make the relationship required by using the aforementioned attribute or changing the fluent API WithOptional to WithRequired . 所以,你的确要好好利用上述属性或改变流畅API所需的关系WithOptionalWithRequired

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在实体框架中对外键应用级联删除 - how to apply cascade-delete on foreign key in entity framework 如何配置实体框架代码第一个集合,其中字符串作为父ID的外键以级联删除? - How to configure Entity Framework Code First collections with strings as foreign keys to parent IDs to cascade delete? 当我有两个外键时,如何在 Entity Framework 6 中正确设置级联删除? - How to set cascade deleting properly in Entity Framework 6 when I have two foreign keys? 实体框架:如何在单向相关实体上启用级联删除 - Entity Framework: How to enable cascade delete on one way related entities 实体框架级联删除 - FOREIGN KEY约束 - Entity Framework Cascade delete - FOREIGN KEY constraint 实体框架多个复合键,在删除时级联 - Entity framework multiple composite keys, cascade on delete 如何在实体框架中级联删除? - How to cascade delete in entity framework? 列出实体框架中外键指向的实体 - Listing entities pointed by foreign keys in Entity Framework 迁移不适用于 ON CASCADE DELETE 行为的所有外键 - Migration doesn't apply on all foreign keys the ON CASCADE DELETE behavior 实体框架对具有列表的实体应用过滤器 - Entity Framework apply filter with entities that have lists
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM