EF Core 迁移失败、数据丢失 手动处理

一、环境

        windows 10

        Visual studio 2022

        dotnet 6.0.404

        Microsoft.EntityFrameworkCore.Tools 6.0.14

二、问题

        有一记录房产交易数据的实体,已有生产数据,现需更改、添加字段,产生了迁移不成功和数据丢失的问题。

        原实体定义

  //唯一复合索引
  [Index(nameof(Name), nameof(TradeDay), IsUnique = true)]
  public class HouseTrade
  {
      [Key]
      [Required]
      public int HouseTradeID { get; set; }

      [Required]
      [MaxLength(100)]
      public string Name { get; set; }
      
      
      public int TotalTrades { get; set; }
      //总面积
      public float TotalArea { get; set; }

      
      public int HouseTrades { get; set; }
      //其中住宅面积
      public float HouseArea { get; set; }
      
      [Required]
      [MaxLength(20)]
      public string TradeDay { get; } = DateTime.Now.ToShortDateString();

      public HouseTrade() 
      {
        
      }

      public string toString() 
      {
          return Name + "\t" + TotalTrades+ "\t" + TotalArea + "\t" + HouseTrades + "\t" + HouseArea+"\t"+TradeDay;
      }

  }

 EF Core 迁移失败、数据丢失 手动处理_第1张图片

        现不再需要记录交易面积,仅简单描述 住宅面积-总面积 以字符串存储就可以。 现在模型中可以删去TotalArea、HouseArea,然后增加字段 Description =  HouseArea + '-' + TotalArea。现模型如下所示:

    //唯一复合索引
    [Index(nameof(Name), nameof(TradeDay), IsUnique = true)]
    public class HouseTrade
    {
        [Key]
        [Required]
        public int HouseTradeID { get; set; }

        [Required]
        [MaxLength(100)]
        public string Name { get; set; }

        public int TotalTrades { get; set; }
        //public float TotalArea { get; set; }

        public int HouseTrades { get; set; }
        //public float HouseArea { get; set; }
        [MaxLength(200),AllowNull]
        public string Description { get; set; }

        [Required]
        [MaxLength(20)]
        public string TradeDay { get; } = DateTime.Now.ToShortDateString();

        public HouseTrade() 
        {
           
        }

        public string toString() 
        {
            return Name + "\t" +  TotalArea + "\t" + HouseTrades + "\t" +Description+"\t"+TradeDay;
        }

    }

        此时若直接用update-database,则原有数据将丢失,所以在生成迁移后,用手动进行更改以保护数据。 

三、解决办法

        在控制台执行Add-Migration 。

PM> Add-Migration addDescription
Build started...
Build succeeded.
An operation was scaffolded that may result in the loss of data. Please review the migration for accuracy.
To undo this action, use Remove-Migration.

默认在Migrations文件下会生成二个文件。

打开20230915024552_addDescription.cs文件,可以看到迁移将要进行的操作,若此时立即操作,原有TotalArea、TradeArea数据将丢失。

       protected override void Up(MigrationBuilder migrationBuilder)
       {
           migrationBuilder.DropColumn(
               name: "HouseArea",
               table: "HouseTrades");

           migrationBuilder.DropColumn(
               name: "TotalTrades",
               table: "HouseTrades");

           migrationBuilder.AddColumn(
               name: "Description",
               table: "HouseTrades",
               type: "nvarchar(200)",
               maxLength: 200,
               nullable: false,
               defaultValue: "");
       }

此时手动修改代码,先创建Description字段,然后再将数据插入,然后再删除旧字段。

       protected override void Up(MigrationBuilder migrationBuilder)
       {

           migrationBuilder.AddColumn(
               name: "Description",
               table: "HouseTrades",
               type: "nvarchar(200)",
               maxLength: 200,
               nullable: false,
               defaultValue: "");

           migrationBuilder.Sql(
               @"
               UPDATE HouseTrades
               SET Description = CONVERT(VARCHAR(30),HouseTrades) + '-' + CONVERT(VARCHAR(30),TotalTrades);
               ");

           migrationBuilder.DropColumn(
               name: "HouseArea",
               table: "HouseTrades");

           migrationBuilder.DropColumn(
               name: "TotalTrades",
               table: "HouseTrades");

       }

保存后再执行,update-database

PM> update-database
Build started...
Build succeeded.
Applying migration '20230915024552_addDescription'.
Done.

 数据迁移成功。

四、参考文章

管理迁移 - EF Core | Microsoft Learn

你可能感兴趣的:(.netcore)