迁移中的默认值不起作用

本文关键字:不起作用 默认值 迁移 | 更新日期: 2023-09-27 18:36:27

我有一个带有EF和代码优先的MVC项目。

我有一个模型 PropBase 和一个模型 MyProp - 它们映射到同一个表(带有自动"鉴别器"列)。

我为 MyProp 添加了两个属性 - prop1 和 prop2:

   public class PropBase
   {
       public double Prop0 { get; set; }
   }
   public class MyProp: PropBase
   {
       public double Prop10 { get; set; }
       public double Prop1{ get; set; }    // new property
       public int Prop2{ get; set; }       // new property
   }

我还添加了一个新的迁移:

    public partial class AddProps12 : DbMigration
    {
        public override void Up()
        {
            AddColumn("dbo.Props", "Prop1", c => c.Double(nullable: true, defaultValue: 0));   
            AddColumn("dbo.Props", "Prop2", c => c.Int(nullable: true, defaultValue: 0));
        }
        public override void Down()
        {
            DropColumn("dbo.Props", "Prop1");
            DropColumn("dbo.Props", "Prop2");
        }
    }

但是当我运行应用程序时 - 新列以 null 和在线添加

  return m_myPropsRepository.AsQueryable().ToList();

我收到此错误

"MyProp"上的"Prop1"属性无法设置为"空"值。 必须将此属性设置为类型为"Double"的非空值。

我不能使用 nullable:false,因为当我向表中插入新的 PropBase 时 - 它不知道 Prop1 和 Prop2,因此插入 NULL,然后我收到错误,因为我将其定义为不可空。

我需要一种方法来使其可为空,并将 0 作为当前 MyProp 行的默认值。

迁移中的默认值不起作用

请尝试

AddColumn("dbo.Props", "Prop1", c => c.Double());   
AddColumn("dbo.Props", "Prop2", c => c.Int());
Sql("UPDATE dbo.Props SET Prop1 = 0, Prop2 = 0 WHERE Discriminator = 'MyProp'");

这个想法是用非空值更新数据库表中的旧值与鉴别器"MyProp"

好的...像下面这样使用

AddColumn("dbo.Props", "Prop2", c => c.Int(nullable: false, defaultValue: 0));

在代码中设置可为空:假

您在数据库中将两个字段添加为可为空(可为空:true),但您的模型(对象)将这些类型声明为不可为空。因此,EF 正在尝试为非 nulalable 属性分配一个 null 值。使对象属性 nulallbe 如下所示:

public class MyProp: PropBase
{
   public double Prop10 { get; set; }
   public double? Prop1{ get; set; }    // new property
   public int? Prop2{ get; set; }       // new property
}

或者,必须在数据库中使列非 nullalbe(可为空:false)。

如果您希望它可为空但仍需要默认值 0,那么您可以执行以下操作:

public class MyProp: PropBase
{
 private double? _prop1;
 private double? _prop2;
 public double Prop10 { get; set; }
 public double? Prop1
 {   
    get
    {
        if(!this._prop1.HasValue)
            this._prop1 = 0;
        return this._prop1;
    }
    set
    {
        this._prop1 = value;
    } 
 }
 public int? Prop2
 {   
    get
    {
        if(!this._prop2.HasValue)
            this._prop2 = 0;
        return this._prop2;
    }
    set
    {
        this._prop2 = value;
    } 
 }    
}