【问题标题】:SQL Error: Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths. Entity Framework CoreSQL 错误:引入 FOREIGN KEY 约束可能会导致循环或多个级联路径。实体框架核心
【发布时间】:2019-06-14 10:05:08
【问题描述】:

我正在使用 SQL 并尝试使用 Entity Framework Core 添加迁移。我不确定如何解决这个问题。它用于将评论系统与用户和产品相关联。这在 SQLite 中有效。现在使用 SQL 服务器。我试图在简短的情况下提供所有内容。如果需要,我可以提供更多。下面是我的代码,有人可以帮忙吗?

访问“程序”类上的 IWebHost 时出错。在没有应用程序服务提供商的情况下继续。错误:在表“ProductReviews”上引入 FOREIGN KEY 约束“FK_ProductReviews_AspNetUsers_ReviewerId”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束或索引。查看以前的错误。

我已经尝试了注释掉的代码。

            protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

    builder.Entity<MemberReview>()
                .HasKey(k => new { k.RevieweeId, k.ReviewerId });

            builder.Entity<MemberReview>().
                HasOne(u => u.Reviewer)
                .WithMany(u => u.ReviewedMembers);
                // .HasForeignKey(u => u.ReviewerId)
                // .OnDelete(DeleteBehavior.Restrict);

            builder.Entity<MemberReview>().
                HasOne(u => u.Reviewee)
                .WithMany(u => u.MemberReviews);
            // .HasForeignKey(u => u.RevieweeId)
            // .OnDelete(DeleteBehavior.Restrict);

            builder.Entity<ProductReview>()
                .HasKey(k => new { k.ReviewerId, k.ReviewedProductId });

            builder.Entity<ProductReview>().
                HasOne(u => u.ReviewedProduct)
                .WithMany(u => u.ProductReviews);
                //.HasForeignKey(u => u.ReviewedProductId)
                //.OnDelete(DeleteBehavior.Restrict);

            builder.Entity<ProductReview>().
                HasOne(u => u.Reviewer)
                .WithMany(u => u.ReviewedProducts);
                //.HasForeignKey(u => u.ReviewerId)
                //.OnDelete(DeleteBehavior.Restrict);
        }

        public class ProductReview
    {
        public Product ReviewedProduct { get; set; }
        public User Reviewer { get; set; }
        [Required]
        public int ReviewerId { get; set; }
        [Required]
        [MaxLength(30)]
        public string ReviewerUserName { get; set; }
        [Required]
        public int ReviewedProductId { get; set; }
        [Required]
        [MaxLength(35)]
        public string Title { get; set; }
        [Required]
        [MaxLength(420)]
        public string Review { get; set; }
        [Required]
        [MaxLength(2)]
        public int Rating { get; set; }
    }

        public class User : IdentityUser<int>
    {
        [Required]
        [MaxLength(12)]
        public string UserType { get; set; }
        [Required]
        public DateTime DateOfEstablishment { get; set; }
        [Required]
        [MaxLength(75)]
        public string KnownAs { get; set; }
        public DateTime Created { get; set; }
        public DateTime LastActive { get; set; }
        [MaxLength(420)]
        public string Description { get; set; }
        public ICollection<Photo> Photos { get; set; }
        public ICollection<Product> Products { get; set; }
        // REVIEW THING
        public ICollection<MemberReview> MemberReviews { get; set; }
        public ICollection<MemberReview> ReviewedMembers { get; set; }
        public ICollection<ProductReview> ReviewedProducts { get; set; }
        // *****
    }

        public class Product
    {
        public int Id { get; set; }
        [Required]
        [MaxLength(75)]
        public string Name { get; set; }
        [Required]
        [MaxLength(420)]
        public string Description { get; set; }
        public DateTime DateAdded { get; set; }
        public User User { get; set; }
        [Required]
        public int UserId { get; set; }
        // REVIEW THINGS
        public ICollection<ProductReview> ProductReviews { get; set; }
        // *****
    }

【问题讨论】:

  • 您正试图在具有级联的表上使用多个外键,但 SQL Server 不允许多个级联操作。如果您想在所有外键上使用类似级联的功能,您需要禁用外键上的级联选项并使用触发器来实现。

标签: c# sql-server asp.net-core foreign-keys entity-framework-core


【解决方案1】:

我刚试过这个:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<MemberReview>()
        .HasKey(e => new { e.RevieweeId, e.ReviewerId });

    builder.Entity<ProductReview>()
        .HasKey(e => new { e.ReviewerId, e.ReviewedProductId });

    builder.Entity<MemberReview>()
        .HasOne<User>(e => e.Reviewer)
        .WithMany(e => e.MemberReviews)
        .HasForeignKey(e => e.ReviewerId)
        .OnDelete(DeleteBehavior.Restrict); ////////
                                                  //
    builder.Entity<MemberReview>()                //
        .HasOne<User>(e => e.Reviewee)            /// => only one of these two can be cascade
        .WithMany(e => e.ReviewedMembers)         //
        .HasForeignKey(e => e.RevieweeId)         //
        .OnDelete(DeleteBehavior.Restrict); ////////

    builder.Entity<ProductReview>()
        .HasOne<User>(e => e.Reviewer)
        .WithMany(e => e.ReviewedProducts)
        .HasForeignKey(e => e.ReviewerId)
        .OnDelete(DeleteBehavior.Restrict);
}

你没有提供 MemberReview 类所以我创建了这个:

public class MemberReview
{
    public User Reviewer { get; set; }
    public int ReviewerId { get; set; }

    public User Reviewee { get; set; }
    public int RevieweeId { get; set; }
}

结果如下:

【讨论】:

  • 非常感谢!这行得通!我改变的一件事是在 MemberReview 上交换 FK。 ReviewerId 在 .HasForeignKey 上变为 RevieweeId,反之亦然...
猜你喜欢
  • 2018-08-08
  • 2021-04-14
  • 2011-05-08
  • 2013-10-22
  • 2019-10-20
  • 2017-04-26
相关资源
最近更新 更多