【问题标题】:How to turn off cascade delete in Entity Framework Core 1.0 RTM如何在 Entity Framework Core 1.0 RTM 中关闭级联删除
【发布时间】:2017-03-14 08:54:41
【问题描述】:

您好,我有带有 Entity Framework Core 1.0 RTM 和 SQL 服务器的 MVC 6 应用程序,当我尝试生成数据库表时,出现“引入 FOREIGN KEY 约束可能导致循环或多个级联路径”错误。

我的模型类如下:

类别模型:

 public class Category
{
    public Category()
    {
        this.VariableSettings = new List<VariableSetting>();
    }
    public int CategoryId { get; set; }

    public string CategoryName { get; set; }

    public List<VariableSetting> VariableSettings { get; set; }

    public List<Station> Stations { get; set; }
}

车站型号:

 public class Station
{
    public int StationId { get; set; }
    public string StationName { get; set; }

    public double? Longitude { get; set; }
    public double? Latitude { get; set; }

    public List<VariableRecord> VariableRecords { get; set; }

    public int CategoryID { get; set; }
    public Category Category { get; set; }
}

变量记录模型:

 public class VariableRecord
{
    [Key]
    public int VariableRecordId { get; set; }
    public double Value { get; set; }
    public DateTime RecordDate { get; set; }

    public int StationId { get; set; }
    public Station Station { get; set; }

    public int VarSettingId{ get; set; }
    public virtual VariableSetting VariableSetting { get; set; }
}

变量设置模型:

public class VariableSetting
{
    [Key]
    public int VarSettingId { get; set; }
    public int Sequence { get; set; }
    public double? MinimumValue { get; set; }
    public double? MaximumValue { get; set; }

    public int CategoryId { get; set; }
    public virtual Category Category { get; set; }

    public int VariableId { get; set; }
    public Variable Variable { get; set; }

    public List<VariableRecord> VariableRecords { get; set; }
}

变量模型:

 public class Variable
{
    public int VariableId { get; set; }

    public string VariableName { get; set; }

    public string Description { get; set; }

    public string Unit { get; set; }

    public List<VariableSetting> VariableSettings { get; set; }
}

所以,在我的代码 Category->Station->VariableRecord 和 Category->VariableSetting->VariableRecord 中也有级联删除路由,所以我试图在上下文类中禁用路由 Category->VariableSetting->VariableRecord Fluent API 如下:

builder.Entity<VariableRecord>()
        .HasOne(pt => pt.VariableSetting)
        .WithMany(p => p.VariableRecords)
        .HasForeignKey(pt => pt.VarSettingId)
        .OnDelete(DeleteBehavior.Cascade);

但是我仍然得到以下相同的结果:

System.Data.SqlClient.SqlException (0x80131904):引入 FOREIGN 表上的 KEY 约束“FK_VariableSetting_Category_CategoryId” 'VariableSetting' 可能会导致循环或多个级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN 关键约束。

我在这些代码上卡了几天,但仍然无处可去,请帮助!

【问题讨论】:

  • 只有一件事,我在核心开发时也发现:尝试使用属性 -> [ForeignKey("")][InverseProperty("")] - 这减少了例如那些错误。 docs.efproject.net/en/latest/modeling/… EFs fluent API 不是我的大爱,所以我不能在不混淆你的情况下写一些东西:D
  • OnDelete(DeleteBehavior.Cascade) 实际上激活了行为,对吗?将DeleteBehavior 更改为其他一些值可能是什么?只是一个猜测,还没有使用核心。

标签: c# sql entity-framework asp.net-core-mvc entity-framework-core


【解决方案1】:

使用DeleteBehavior.Restrict 而不是DeleteBehavior.Cascade

您已经有多个级联路径,因此如果您想要(好的,您需要)禁用其中一个的级联 - 使用 DeleteBehavior.Restrict

【讨论】:

    【解决方案2】:

    如果您遵循命名约定,您只需要类定义和一些注释(使用 EF Core 1.0.1)

    public class Category
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
    
        //[InverseProperty( nameof( VariableSetting.Category ) )]
        public virtual ICollection<VariableSetting> VariableSettings { get; set; }
            = new List<VariableSetting>();
    
        //[InverseProperty( nameof( Station.Category ) )]
        public virtual ICollection<Station> Stations { get; set; } 
            = new List<Station>();
    }
    
    public class Station
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        public double? Longitude { get; set; }
        public double? Latitude { get; set; }
    
        //[InverseProperty( nameof( VariableRecord.Station ) )]
        public virtual ICollection<VariableRecord> VariableRecords { get; set; }
            = new List<VariableRecord>();
    
        [Required]
        public int CategoryId { get; set; }
    
        //[ForeignKey( nameof( CategoryId ) )]
        public virtual Category Category { get; set; }
    }
    
    public class VariableRecord
    {
        [Key]
        public int Id { get; set; }
        public double Value { get; set; }
        public DateTime RecordDate { get; set; }
    
        [Required]
        public int StationId { get; set; }
    
        //[ForeignKey( nameof( StationId ) )]
        public virtual Station Station { get; set; }
    
        [Required]
        public int VariableSettingId { get; set; }
    
        //[ForeignKey( nameof( VariableSettingId ) )]
        public virtual VariableSetting VariableSetting { get; set; }
    }
    
    public class VariableSetting
    {
        [Key]
        public int Id { get; set; }
        public int Sequence { get; set; }
        public double? MinimumValue { get; set; }
        public double? MaximumValue { get; set; }
    
        [Required]
        public int CategoryId { get; set; }
    
        //[ForeignKey( nameof( CategoryId ) )]
        public virtual Category Category { get; set; }
    
        [Required]
        public int VariableId { get; set; }
    
        //[ForeignKey( nameof( VariableId ) )]
        public virtual Variable Variable { get; set; }
    
        //[InverseProperty( nameof( VariableRecord.VariableSetting ) )]
        public virtual ICollection<VariableRecord> VariableRecords { get; set; }
            = new List<VariableRecord>();
    }
    
    public class Variable
    {
        [Key]
        public int Id { get; set; }
    
        [Required]
        public string Name { get; set; }
        public string Description { get; set; }
        public string Unit { get; set; }
    
        //[InverseProperty( nameof( VariableSetting.Variable ) )]
        public virtual ICollection<VariableSetting> VariableSettings { get; set; }
            = new List<VariableSetting>();
    }
    

    如果您想使用其他名称,请取消注释所有注释并修复名称。

    创建的(SQLite)sql结构是

    PRAGMA foreign_keys = false;
    
    -- ----------------------------
    --  Table structure for "Categories"
    -- ----------------------------
    DROP TABLE IF EXISTS "Categories";
    CREATE TABLE "Categories" (
        "Id" INTEGER NOT NULL CONSTRAINT "PK_Categories" PRIMARY KEY AUTOINCREMENT,
        "Name" TEXT NOT NULL
    );
    
    -- ----------------------------
    --  Table structure for "Stations"
    -- ----------------------------
    DROP TABLE IF EXISTS "Stations";
    CREATE TABLE "Stations" (
        "Id" INTEGER NOT NULL CONSTRAINT "PK_Stations" PRIMARY KEY AUTOINCREMENT,
        "CategoryId" INTEGER NOT NULL,
        "Latitude" REAL,
        "Longitude" REAL,
        "Name" TEXT NOT NULL,
        CONSTRAINT "FK_Stations_Categories_CategoryId" FOREIGN KEY ("CategoryId") REFERENCES "Categories" ("Id") ON DELETE CASCADE
    );
    
    -- ----------------------------
    --  Table structure for "Variable"
    -- ----------------------------
    DROP TABLE IF EXISTS "Variable";
    CREATE TABLE "Variable" (
        "Id" INTEGER NOT NULL CONSTRAINT "PK_Variable" PRIMARY KEY AUTOINCREMENT,
        "Description" TEXT,
        "Name" TEXT NOT NULL,
        "Unit" TEXT
    );
    
    -- ----------------------------
    --  Table structure for "VariableRecord"
    -- ----------------------------
    DROP TABLE IF EXISTS "VariableRecord";
    CREATE TABLE "VariableRecord" (
        "Id" INTEGER NOT NULL CONSTRAINT "PK_VariableRecord" PRIMARY KEY AUTOINCREMENT,
        "RecordDate" TEXT NOT NULL,
        "StationId" INTEGER NOT NULL,
        "Value" REAL NOT NULL,
        "VariableSettingId" INTEGER NOT NULL,
        CONSTRAINT "FK_VariableRecord_Stations_StationId" FOREIGN KEY ("StationId") REFERENCES "Stations" ("Id") ON DELETE CASCADE,
        CONSTRAINT "FK_VariableRecord_VariableSetting_VariableSettingId" FOREIGN KEY ("VariableSettingId") REFERENCES "VariableSetting" ("Id") ON DELETE CASCADE
    );
    
    -- ----------------------------
    --  Table structure for "VariableSetting"
    -- ----------------------------
    DROP TABLE IF EXISTS "VariableSetting";
    CREATE TABLE "VariableSetting" (
        "Id" INTEGER NOT NULL CONSTRAINT "PK_VariableSetting" PRIMARY KEY AUTOINCREMENT,
        "CategoryId" INTEGER NOT NULL,
        "MaximumValue" REAL,
        "MinimumValue" REAL,
        "Sequence" INTEGER NOT NULL,
        "VariableId" INTEGER NOT NULL,
        CONSTRAINT "FK_VariableSetting_Categories_CategoryId" FOREIGN KEY ("CategoryId") REFERENCES "Categories" ("Id") ON DELETE CASCADE,
        CONSTRAINT "FK_VariableSetting_Variable_VariableId" FOREIGN KEY ("VariableId") REFERENCES "Variable" ("Id") ON DELETE CASCADE
    );
    
    -- ----------------------------
    --  Indexes structure for table "Stations"
    -- ----------------------------
    CREATE INDEX "IX_Stations_CategoryId" ON "Stations" ("CategoryId");
    
    -- ----------------------------
    --  Indexes structure for table "VariableRecord"
    -- ----------------------------
    CREATE INDEX "IX_VariableRecord_StationId" ON "VariableRecord" ("StationId");
    CREATE INDEX "IX_VariableRecord_VariableSettingId" ON "VariableRecord" ("VariableSettingId");
    
    -- ----------------------------
    --  Indexes structure for table "VariableSetting"
    -- ----------------------------
    CREATE INDEX "IX_VariableSetting_CategoryId" ON "VariableSetting" ("CategoryId");
    CREATE INDEX "IX_VariableSetting_VariableId" ON "VariableSetting" ("VariableId");
    
    PRAGMA foreign_keys = true;
    

    如您所见,级联删除无需关闭:o)

    【讨论】:

      猜你喜欢
      • 2017-06-02
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      • 2016-01-17
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 2016-11-09
      相关资源
      最近更新 更多