Loading

EFCore ORM 数据库数据表迁移

背景

项目初期建表时,没有考虑到后续拓展性,错误地将描述字段添加到了关系表,关系表应该只能存放关系。需要将描述迁移到寄存器表中。

技术栈:EFCore ORM、SQLite3

概述

本文记录一下迁移的过程,有类似的需求以便参考。

本次迁移一共分为 5 步走:

  1. 目标表新增描述字段
  2. 迁移数据库表结构
  3. 编写、执行脚本复制描述字段数据
  4. 删除代码中原字段、修改对原字段的引用
  5. 检查无误后迁移数据表结构

目标表新增描述字段

image

目标表新增属性 Description

迁移数据库表结构

执行下面的命令

dotnet ef migrations add AddDescriptionToSpecialRegister
dotnet ef database update

现在迁移好的目标表中已有新的字段了。注意这里新的数据库文件位置取决于自己指定的数据库路径:

 	public class DataContext : DbContext
    {
        public DataContext()
        {
            string folder = AppDomain.CurrentDomain.BaseDirectory;
            string path = Path.Combine(folder, "data.db");
            DbPath = path;
        }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlite($"FileName={DbPath}");
        }
	}

我这里项目属性设置了始终复制源代码中的 data.db 到 bin 目录,所以每次数据库迁移完,要手动替换数据库文件。觉得麻烦就先关掉始终复制,所有迁移完成后再替换;或者开发/迁移阶段直接指定使用源代码中的数据库文件。

编写、执行脚本复制描述字段数据

class Program
{
    static void Main()
    {
        DataContext context = new DataContext();

        // 输出当前使用的数据库路径
        Console.WriteLine($"当前使用的数据库路径: {context.Database.GetConnectionString()}");
        using (var transaction = context.Database.BeginTransaction())
        {
            try
            {
                var descriptions = context.CpuSpecialRegisterAssociations.ToList();
                foreach (var d in descriptions)
                {
                    var description = d.Description;
                    var specialRegister = context.SpecialRegisters.First(x => x.Id == d.SpecialRegisterId);
                    specialRegister.Description = description;
                }

                context.SaveChanges();
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                Console.WriteLine($"迁移过程中出错: {ex.Message}");
                Console.WriteLine(ex.StackTrace);
            }
        }
    }
}

删除代码中原字段、修改对原字段的引用

删除原表中的描述属性。这时候直接执行dotnet ef migrations add xxxx会编译不通过,因为很多地方用了这个描述属性,而它被删除了。

修改之前引用这个属性的代码。修改完成后,可以使用 dotnet build检查一下编译是否通过。

如果编译通过了,就可以进行下一步。

检查无误后迁移数据表结构

执行以下命令

dotnet ef migrations add RemoveDescriptionInCpuSpecialRegisterAssociation
dotnet ef database update

执行完毕后,数据库中关系表中的描述字段就被删掉了。

总结

自此完成了数据库两表之间的数据迁移。可根据自己的情况进行数据库文件的替换(若数据库源文件与修改的文件不是相同的)

posted @ 2025-05-08 00:17  sq800  阅读(37)  评论(0)    收藏  举报