代码之家  ›  专栏  ›  技术社区  ›  Yitzchak

实体框架6如何决定fk是否应使用on delete cascade定义

  •  1
  • Yitzchak  · 技术社区  · 6 年前

    我有一堆相互关联的课程。

    以下面的类层次结构为例:

    Class A
    {
        // PK
        public string A_Id
    
        // Navigation Property
        public virtual ICollection<B> MyB{ get; set; }
    }
    
    
    Class B
    {
        // PK
        public int B_Id
    
        // FK - On Delete - NO ACTION     <---------- Difference here
        public string A_Id { get; set; }
    
        // Navigation Properties
        public virtual A MyA { get; set; }
        public List<C> MyC{ get; set; }
    }
    
    Class C
    {
        // PK
        public int C_Id
    
        // FK - On Delete - CASCADE     <---------- Difference here
        public int B_Id { get; set; }
    
        // Navigation Properties
        public virtual B MyB { get; set; }
    }
    

    当我检查FKS的时候 SQL管理工作室 我看到on delete cascade定义在 C类FK ,但不在 B类FK .

    另外,当我尝试删除的实例时,会得到不同的运行时异常,因为有引用该实例的行。

    为什么会这样?

    在delete cascade上,我应该如何定义它们?

    EF6如何确定如何定义FKS?是吗?

    我读过很多这样的答案,但都没有成功。

    我还试图用 流畅的API ,但它只是创建了第二个FK,而不是修改第一个FK。=[

    2 回复  |  直到 6 年前
        1
  •  2
  •   Yitzchak    6 年前

    好吧,在这里苦苦挣扎之后,正确的答案是:

    实体框架默认行为为“on delete cascade”

    但它只能在列不可为空时定义“on delete cascade”。

    所以如果我们回到这个例子,我们可以看到类A有一个 一串 主键( 可为空 )B级有一个 内景 主键( 非空的 )中。这就解释了区别。

    怎么解决?

    最好的解决办法是 [必需] 属性位于 FK属性,否则,EF6引擎将把该属性视为 可为空并在删除时定义->无操作!

    工作示例:

    Class A
    {
        // PK
        public string A_Id
    
        // Navigation Property
        public virtual ICollection<B> MyB{ get; set; }
    }
    
    
    Class B
    {
        // PK
        public int B_Id
    
        // FK - On Delete - NO ACTION     <---------- Difference here
        [Required]          <------------------------ SOLUTION =] =] =]
        public string A_Id { get; set; }
    
        // Navigation Properties
        public virtual A MyA { get; set; }
        public List<C> MyC{ get; set; }
    }
    
    Class C
    {
        // PK
        public int C_Id
    
        // FK - On Delete - CASCADE     <---------- Difference here
        public int B_Id { get; set; }
    
        // Navigation Properties
        public virtual B MyB { get; set; }
    }
    
        2
  •  1
  •   Zeeshan Adil    6 年前

    在你的 数据库上下文 类使用fluentapi可以完成此操作,如下所示:

     protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<A>()
                .HasOptional(a => a.MyB)
                .WithOptionalDependent()
                .WillCascadeOnDelete(true);
        }
    

    它使您可以灵活地使用非必需字段。