简体   繁体   English

实体框架核心多对多关系有问题

[英]Having trouble with entity framework core many to many relation

I am designing a database i have three models(user, movie, review).The idea is each user can submit a movie each user can leave a review for a movie.The user model has ICollection and ICollecyion, the movie model has foreign key UserId and ICollection, and the review model has foreign keys for UserId and MovieId.我正在设计一个数据库,我有三个模型(用户,电影,评论)。这个想法是每个用户可以提交电影每个用户可以对电影发表评论。用户 model 有 ICollection 和 ICollecyion,电影 model 有外键UserId 和 ICollection,评论 model 具有 UserId 和 MovieId 的外键。 When i try update-database i get this error:当我尝试更新数据库时,我收到此错误:

Introducing FOREIGN KEY constraint 'FK_Review_User_UserId' on table 'Review' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

Here are my models:这是我的模型:

 public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Username { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public int FavouriteGenre { get; set; }
    public ICollection<Movie> SubmittedMovies { get; set; }
    public ICollection<Review> SubmittedReviews { get; set; }
}

public class Movie
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string PosterUrl { get; set; }
    public int Year { get; set; }
    public int Genre { get; set; }
    public DateTime Posted { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
    public ICollection<Review> Reviews { get; set; }
}

 public class Review
{
    public int Id { get; set; }
    public int Rating { get; set; }
    public string UserReview { get; set; }
    public int MovieId { get; set; }
    public Movie Movie { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
    public DateTime Posted { get; set; }
}

And my on creating method in the dbContext:我在 dbContext 中创建方法:

 protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Review>()
            .HasOne(r => r.User)
            .WithMany(u => u.SubmittedReviews)
            .HasForeignKey(r => r.UserId);

        builder.Entity<Review>()
            .HasOne(r => r.Movie)
            .WithMany(m => m.Reviews)
            .HasForeignKey(r => r.MovieId);
        
    }

I have tried this:我试过这个:

builder.Entity<Review>()
                .HasOne(r => r.User)
                .WithMany(u => u.SubmittedReviews)
                .HasForeignKey(r => r.UserId)
                .IsRequired(false)
                .OnDelete(DeleteBehavior.Restrict);

 builder.Entity<Review>()
                .HasOne(r => r.Movie)
                .WithMany(m => m.Reviews)
                .HasForeignKey(r => r.MovieId)
                .IsRequired(false)
                .OnDelete(DeleteBehavior.Restrict);

I have also tried making the foreign keys in the Review model nullable(i have tried separately and both at the same time) with DeleteBehaviour.Restrict in the context, but nothing seems to work, when i deleted a movie it worked well, but when i tried to delete a user i got this error in SSMS:我还尝试在上下文中使用 DeleteBehaviour.Restrict 使 Review model 中的外键为空(我分别尝试过,并且同时尝试过),但似乎没有任何效果,当我删除一部电影时效果很好,但是当我试图删除一个用户,但在 SSMS 中出现此错误:

The DELETE statement conflicted with the REFERENCE constraint "FK_Review_User_UserId". The conflict occurred in database "MovieDb", table "dbo.Review", column 'UserId'.

I think i understand the problem but i cant find a solution.我想我理解这个问题,但我找不到解决方案。

From this article这篇文章

In SQL Server, a table cannot appear more than one time in a list of all the cascading referential actions that are started by either a DELETE or an UPDATE statement.在 SQL 服务器中,一个表不能在由 DELETE 或 UPDATE 语句启动的所有级联引用操作的列表中出现多次。 For example, the tree of cascading referential actions must only have one path to a particular table on the cascading referential actions tree例如,级联引用操作树必须只有一个路径到级联引用操作树上的特定表

Your schema contains a circular reference because a user can have a review on their own movie.您的架构包含循环引用,因为用户可以对自己的电影进行评论。

Here's what's (potentially) happening when you try to delete a user:以下是您尝试删除用户时(可能)发生的情况:

  • Reviews related to that user are cascade-deleted与该用户相关的评论被级联删除
  • Movies related to that user are cascade-deleted与该用户相关的电影被级联删除
  • Reviews related to that movie are cascade-deleted与该电影相关的评论被级联删除

The last two points there are what is causing the issue.最后两点是导致问题的原因。 Since both User and Movie have (I'm assuming) required relationships, you can have a scenario where the DB tries to delete the same record twice because it has a foreign key reference to a User and that same review is on a movie that the User created.由于 User 和 Movie 都具有(我假设)必需的关系,因此您可能会遇到这样一种情况,即 DB 尝试删除相同的记录两次,因为它具有对 User 的外键引用,并且相同的评论是在电影上的用户创建。

I would make the UserId field nullable/optional on the Reviews table.我会让评论表上的UserId字段为空/可选。 Based on your description, I'm not sure if you set the property to be nullable as well, but your code should look like this:根据您的描述,我不确定您是否也将属性设置为可为空,但您的代码应如下所示:

public class Review
{
    // Other fields hidden
    public int? UserId { get; set; }
    // ...
}

In your FluentAPI model builder definitions, you can set Movie Reviews to cascade, and SubmittedReviews on the users table to restrict on delete.在您的 FluentAPI model 构建器定义中,您可以将 Movie Review 设置为级联,并将用户表上的 SubmittedReviews 设置为限制删除。 You can also remove the .IsRequired(false) line from the model builder definition for Movie Reviews您还可以从电影评论的 model 构建器定义中删除.IsRequired(false)

Personally, this is why I just use "Soft Delete" columns (like DeletedBy , DeletedOn ) in models with lots of dependent relationships.就个人而言,这就是为什么我只在具有大量依赖关系的模型中使用“软删除”列(如DeletedByDeletedOn )。 It's a bit more involved in your API code, as you have to manually go in and delete/mark as deleted the related records, but it prevents headaches like this.您的 API 代码涉及更多,因为您必须手动输入 go 并删除/标记为已删除的相关记录,但它可以防止这样的头痛。

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

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