Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET 5 (MVC6) EF7 Foreign Key may cause cycles

Here are my models:

public class Post
{

    [Key]
    public int PostId { get; set; }

    [Required]
    [MaxLength(140)]
    public string Title { get; set; }

    [Required]
    public string ApplicationUserId { get; set; }

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

public class Comment
{
    [Key]
    public int CommentId { get; set; }

    [Required]
    [StringLength(1000)]
    public string Text { get; set; }

    [Required]
    public int PostId { get; set; }

    [Required]
    public string ApplicationUserId { get; set; }


    public Post Post { get; set; }
    public ApplicationUser ApplicationUser { get; set; }

}

I am getting the error:

Introducing FOREIGN KEY constraint 'FK_Comment_Post_PostId' on table 'Comment' 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 or index. See previous errors.

This is exactly how it is demonstrated in their documents.

Now if I remove:

[Required]
public int PostId { get; set; }

and use Fluent API as follows:

builder.Entity<Comment>().HasOne(p => p.Post).WithMany(c => c.Comments).IsRequired();

I still get the same error. If I explicitly state

builder.Entity<Comment>().HasOne(p => p.Post).WithMany(c => c.Comments).IsRequired().OnDelete(DeleteBehavior.Cascade);

I still get the same error.

If I use the following:

builder.Entity<Comment>().HasOne(p => p.Post).WithMany(c => c.Comments);

A comment can be entered without a Post. A comment must belong to a post.

Am I missing something? This is a common use case, a 1 to many relationship with a required FK to a PK.

like image 964
DanielC Avatar asked Dec 25 '22 09:12

DanielC


1 Answers

I was indeed missing something. My structure is that a User can have a Post. A Post can have Comments. Since a Comment also has a User, this is what was causing the cyclic issue.

When a Post is deleted it will cascade delete the Comment. Which is what we want.

When a User is deleted, it would cascade the delete to a Post and a Comment. But a Post will also attempt to cascade delete to Comment.

The solution I used was to remove the cascade delete from User to Comment.

This is done by the following:

builder.Entity<Comment>().HasOne(c => c.ApplicationUser).WithMany(u => u.Comments).IsRequired().OnDelete(DeleteBehavior.Restrict);
like image 134
DanielC Avatar answered Dec 29 '22 05:12

DanielC