简体   繁体   中英

Explanation about Cascade on Delete in Entity Framework

I need a thorough explanation on cascade on delete because it is giving me unnecessary headache. I have a class News.cs and a class Comment.cs. News has a collection of comments and a comment must belong to a News, so I set up my class like below

public class News
{
    public int NewsId { get; set; }

    [Display(Name = "Title")]
    public string Title { get; set; }

    [Display(Name = "Details")]
    public string Details { get; set; }

    public DateTime DateCreated { get; set; }

    public int AppUserId { get; set; }

    [ForeignKey("AppUserId")]
    public virtual AppUser AppUser { get; set; }

    public ICollection<Comment> Comment { get; set; }

}

public class Comment
{
    public int CommentId { get; set; }

    public string CommentText { get; set; }

    public DateTime DateCreated { get; set; }

    public int AppUserId  { get; set; }

    public int NewsId { get; set; }

    [ForeignKey("AppUserId")]
    public virtual AppUser User { get; set; }

    [ForeignKey("NewsId")]
    public virtual News News { get; set; }

}

The behaviour I'm expecting is that if I delete a comment it shouldn't affect the parent news but if I delete a news I don't see any reason to retain the children comments so comments should be deleted. I ran an update database command in package manager console and I kept getting this error

Introducing FOREIGN KEY constraint 'FK_dbo.Comments_dbo.News_NewsId' on table 'Comments' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint. See previous errors. How do I solve this problem?

This error is caused when by deleting one entity, another entity will be deleted more that once.

In your scenario, if you delete AppUser with cascade delete turned on, this will attempt to delete the dependent entities, News and Comment. As Comment is also dependent on News, When News is deleted, Comment will be deleted as a dependent (again). As it may have already been deleted due to the dependency on AppUser, SQL cannot guarantee that the entity now exists, so SQL Server will prevent you from implementing this in the first place.

To resolve, the simplest thing is to turn off cascade delete on one or more of the dependents via the fluent api:

modelBuilder.Entity<AppUser>().HasMany(au => au.Comments)
.WithRequired(c => c.AppUser)
.HasForeignKey(c => c.AppUserID)
.WillCascadeOnDelete(false);

modelBuilder.Entity<AppUser>().HasMany(au => au.News)
.WithRequired(n => n.AppUser)
.HasForeignKey(n => n.AppUserID)
.WillCascadeOnDelete(false);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM