ASP.Net MVC 3 EF“在表上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径”

Posted

技术标签:

【中文标题】ASP.Net MVC 3 EF“在表上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径”【英文标题】:ASP.Net MVC 3 EF "Introducing FOREIGN KEY constraint on table may cause cycles or multiple cascade paths" 【发布时间】:2012-05-02 12:54:21 【问题描述】:

我正在创建一个 ASP.Net MVC 3 应用程序,但在尝试使用迁移更新我的数据库时遇到了外键约束问题。我正在使用 Code-First,我得到的错误是:

在表“CategoryItemValues”上引入 FOREIGN KEY 约束“FK_CategoryItemValues_CategoryProperties_CategoryPropertyId”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束。查看以前的错误。

这是我的课程:

public class Category

    public int Id  get; set; 
    [Display(Name = "Category Name")]
    public string CategoryName  get; set; 
    [Display(Name = "Display Name")]
    public string DisplayName  get; set; 
    [Display(Name = "Display Order")]
    public int DisplayOrder  get; set; 
    public bool IsTab  get; set; 
    public bool Active  get; set; 

    public virtual List<CategoryProperty> Properties  get; set; 


public class CategoryProperty

    public int Id  get; set; 
    public int CategoryId  get; set; 
    [Display(Name="Property Name")]
    public string PropertyName  get; set; 
    [Display(Name = "Display Order")]
    public int DisplayOrder  get; set; 

    public virtual Category Category  get; set; 


public class CategoryItem

    public int Id  get; set; 
    public int CategoryId  get; set; 

    public virtual Category Category  get; set; 
    public virtual List<CategoryItemValue> Values  get; set; 


public class CategoryItemValue

    public int Id  get; set; 
    public int CategoryItemId  get; set; 
    public int CategoryPropertyId  get; set; 
    public string Value  get; set; 

    public virtual CategoryItem Item  get; set; 
    public virtual CategoryProperty Property  get; set; 


protected override void OnModelCreating(DbModelBuilder modelBuilder)

    // I know that the solution needs to go here!

似乎我需要为 CategoryItemValues 禁用 Cascade on Delete,但我不知道该怎么做。我知道我需要这样做:

modelBuilder.Entity<...>() .HasRequired(...) 。与许多(...) .HasForeignKey(...) .WillCascadeOnDelete(false);

但我不能完全正确。

【问题讨论】:

【参考方案1】:

这应该可行...

public class Category

    public int Id  get; set; 
    public string CategoryName  get; set; 
    public string DisplayName  get; set; 
    public int DisplayOrder  get; set; 
    public bool IsTab  get; set; 
    public bool Active  get; set; 
    public virtual List<CategoryProperty> Properties  get; set; 
    public virtual List<CategoryItem> Items  get; set; 

public class CategoryProperty

    public int Id  get; set; 
    public int CategoryId  get; set; 
    public string PropertyName  get; set; 
    public int DisplayOrder  get; set; 
    public virtual Category Category  get; set; 
    public virtual List<CategoryItemValue> Values  get; set; 

public class CategoryItem

    public int Id  get; set; 
    public int CategoryId  get; set; 
    public virtual Category Category  get; set; 
    public virtual List<CategoryItemValue> Values  get; set; 

public class CategoryItemValue

    public int Id  get; set; 
    public int CategoryItemId  get; set; 
    public int CategoryPropertyId  get; set; 
    public string Value  get; set; 
    public virtual CategoryItem Item  get; set; 
    public virtual CategoryProperty Property  get; set; 

...以及“要点”...

modelBuilder.Entity<CategoryProperty>()
    .HasKey(i => i.Id);

modelBuilder.Entity<CategoryProperty>()
    .HasRequired(i => i.Category)
    .WithMany(u => u.Properties)
    .HasForeignKey(i => i.CategoryId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<CategoryItem>()
    .HasKey(i => i.Id);

modelBuilder.Entity<CategoryItem>()
    .HasRequired(i => i.Category)
    .WithMany(u => u.Items)
    .HasForeignKey(i => i.CategoryId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<CategoryItemValue>()
    .HasKey(i => i.Id);

modelBuilder.Entity<CategoryItemValue>()
    .HasRequired(i => i.Item)
    .WithMany(u => u.Values)
    .HasForeignKey(i => i.CategoryItemId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<CategoryItemValue>()
    .HasRequired(i => i.Property)
    .WithMany(u => u.Values)
    .HasForeignKey(i => i.CategoryPropertyId)
    .WillCascadeOnDelete(false);

【讨论】:

@JotDhaliwal 在您的 DbContext 类实现中,覆盖 OnModelCreating(DbModelBuilder modelBuilder) - 这是典型用法,或者您可以使用每个实体的 EntityTypeConfiguration(有点不同但相似) 我有一个问题你能帮我解决这个问题吗@NSGaga @JotDhaliwal 我可以尝试,不过很忙,最好是发布一个问题(因为这里有很多聪明的人可以提供帮助,您可以将这个问题称为“初学者”)只需在此处发表评论并附上链接供我查看

以上是关于ASP.Net MVC 3 EF“在表上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径”的主要内容,如果未能解决你的问题,请参考以下文章

[ASP.NET MVC]: - EF框架学习手记

ASP.NET MVC 的三层架构 + EF数据模型

Asp.Net MVC EF各版本区别

ASP.Net MVC 3 EF“在表上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径”

ASP.NET MVC5+EF6搭建三层实例

当使用带有 EF 4.1 Code First 的 ASP.NET MVC 3 时,我只能编辑主表,我做错了啥?