【问题标题】:Cannot insert the value NULL into column error message无法将值 NULL 插入列错误消息
【发布时间】:2019-06-02 20:00:14
【问题描述】:

我正在尝试运行迁移。迁移完成,但是,当我尝试更新数据库时,我收到此错误消息

无法将值 NULL 插入到列“scheduleDateAndTimeid”、表“aspnet-ScheduleWebApp-20190525082521.dbo.Students”中;列不允许空值。更新失败。

我有两个模型类,一个叫student,另一个叫scheduleDateAndTime

我在student 模型上创建了一个带有映射的DTO,并向scheduleDateAndTime 添加了一个导航属性

迁移

public partial class AnotherMigrationTwoTWOTwotwo : DbMigration
{
    public override void Up()
    {
        DropForeignKey("dbo.Students", "scheduleDateAndTime_id", "dbo.ScheduleDateAndTimes");
        DropIndex("dbo.Students", new[] { "scheduleDateAndTime_id" });
        RenameColumn(table: "dbo.Students", name: "scheduleDateAndTime_id", newName: "scheduleDateAndTimeid");
        AlterColumn("dbo.Students", "scheduleDateAndTimeid", c => c.Int(nullable: false));
        CreateIndex("dbo.Students", "scheduleDateAndTimeid");
        AddForeignKey("dbo.Students", "scheduleDateAndTimeid", "dbo.ScheduleDateAndTimes", "id", cascadeDelete: true);
    }

    public override void Down()
    {
        DropForeignKey("dbo.Students", "scheduleDateAndTimeid", "dbo.ScheduleDateAndTimes");
        DropIndex("dbo.Students", new[] { "scheduleDateAndTimeid" });
        AlterColumn("dbo.Students", "scheduleDateAndTimeid", c => c.Int());
        RenameColumn(table: "dbo.Students", name: "scheduleDateAndTimeid", newName: "scheduleDateAndTime_id");
        CreateIndex("dbo.Students", "scheduleDateAndTime_id");
        AddForeignKey("dbo.Students", "scheduleDateAndTime_id", "dbo.ScheduleDateAndTimes", "id");
    }
}

StudentDto模型类:

public class StudentDto
{
    public int id { get; set; }
    public string name { get; set; }
    public byte age { get; set; }
    public string subjectStudying { get; set; }
    public string disability { get; set; }
    public string additionalInformation { get; set; }
    public ScheduleDateAndTimeDto ScheduleDateAndTime { get; set; }
    public int scheduleDateAndTimeid { get; set; }
}

【问题讨论】:

  • 可能您在要重命名并设置为 nullable = false 的列中有一些空值
  • 这是迁移的问题之一,很难添加新的非空列。如果需要Student.ScheduleDateAndTime,则必须在添加(或启用)FK 约束之前创建ScheduleDateAndTime 记录。

标签: c# asp.net entity-framework


【解决方案1】:

您正在尝试通过将可为空的外键设为不可为空的外键来更新表:如果您使用的是空表(无记录),则此操作将正常工作,但如果存在现有记录,则迁移可能会在该列的这些记录中遇到 NULL 值(迁移前这是一个有效值)

这听起来像是一个限制,但绝对有道理:如果您将列更新为不可为空,迁移应该如何处理现有数据? (考虑生产环境释放等。)

解决方法可能是首先保持列可为空,然后更新现有记录的所有 NULL 值,然后使其不可为空。

【讨论】:

    【解决方案2】:

    您在该列中有一个null 值。在此迁移之前进行某种更新(例如 Sql("UPDATE t SET c = 1 WHERE c IS NULL") 对这些 null 值进行迁移。

    【讨论】:

      【解决方案3】:

      不要破坏数据库以插入无效数据或破坏参照完整性,而是做正确的事情并规范化您的数据:

      CREATE TABLE StudentSchedule (
          studentID INT FOREIGN KEY Students.id,
          scheduleID INT FOREIGN KEY ScheduleDateAndTimes.id
      )
      

      删除Students.scheduleDateAndTime_id。当您获得Students.scheduleDateAndTime_id 时,在StudentSchedule 中插入一行。如果一个学生只能拥有一个 scheduleDateAndTimeid,则将 StudentSchedule.studentID 设为唯一。

      【讨论】:

      • 但这不会(也不能)像不可为空的 FK 那样使关联成为必需的。此外,规范化是通过分析键属性依赖关系来减少冗余。此添加的表不会提高任何规范化级别。从规范化的角度来看,它甚至是多余的,因为 1:1 相关表中的所有字段都可能在一个表中。因此,这只是一种以不显眼的方式向现有模型添加关系的方法。它可能有用,但不能更好地标准化。
      • 归一化,因为所描述的关系不是 1:1。阅读问题,他试图插入一个空 scheduleDateAndTimeid。接受的答案表明一个空外键!两者都不是 1:1,他需要一个交集表来保持参照完整性。
      • Student-StudentSchedule 如果要表示StudentSchedule 之间的1:n,则为1:1。 OP 想要一个必需的关系,而接受的答案提出了一种实现这一目标的方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多