UWP项目升级后SQLite EF迁移崩溃,如何复用数据库文件?
解决方案:兼容旧迁移历史+平滑迁移旧数据
首先明确:把旧项目的Migrations文件夹完整复制到新项目是完全可行的,这也是解决迁移冲突最稳妥的方式,不过需要配合几个关键操作来确保迁移历史匹配,同时实现旧Db1数据到Db2的平滑过渡,具体步骤如下:
一、确保迁移历史完全匹配
- 完整复制旧Migrations文件夹:把旧项目里的Migrations文件夹(包含所有迁移文件和
YourDbContextModelSnapshot.cs)复制到你现在存放数据库代码的.NET标准库项目中,确保文件结构、文件名、类名和旧项目完全一致,尤其是那个导致冲突的MyFirstMigration。 - 验证模型快照一致性:因为你说模型保持不变,所以新项目里的
ModelSnapshot必须和旧项目的完全相同——这是EF判断模型和迁移是否匹配的核心依据。如果有差异,EF会认为模型变更了,依然会触发冲突。 - 配置DbContext指向Db2:在新项目的DbContext配置(比如
OnConfiguring方法或依赖注入配置)中,确保连接字符串指向Db2.db,不要再指向旧的Db1。
二、平滑迁移旧用户的Db1数据
为了让老用户能访问到原来Db1里的数据,需要在App启动时做一次数据迁移:
- 检测旧数据库是否存在:在
App.xaml.cs的启动逻辑中,先检查应用数据目录下是否存在Db1.db(可以用StorageFolder.GetFolderFromPathAsync结合应用的本地数据路径来判断)。 - 双向DbContext实例迁移数据:
- 创建一个临时的旧DbContext实例,连接字符串指向
Db1.db; - 再创建新项目的DbContext实例,连接字符串指向
Db2.db; - 遍历旧DbContext中的所有实体数据,逐一复制到新DbContext中,然后调用
SaveChanges()提交; - 建议用事务包裹整个迁移过程,避免中途出错导致数据不一致;如果数据量较大,可以分批次处理,避免内存占用过高。
- 创建一个临时的旧DbContext实例,连接字符串指向
- 可选:备份旧数据库:迁移完成后,可以把
Db1.db重命名为Db1_backup.db保留一段时间,避免用户需要回溯旧数据的情况。
三、确保后续新项目的迁移兼容性
因为你后续还要创建新项目适配新SDK,且模型不变,只要做到以下两点就能复用同一数据库文件:
- 每次创建新项目时,都要把完整的Migrations文件夹复制过去,不要重新生成新的初始迁移;
- 新项目启动时执行
DBContext.Migrate()即可——EF会读取Db2.db中的__EFMigrationsHistory表,匹配已有的迁移记录,不会再触发冲突。
替代方案:手动同步迁移历史记录
如果你不想复制整个Migrations文件夹,也可以手动同步迁移历史:
- 在新项目中创建一个和旧项目
MyFirstMigration完全一致的迁移(类名、迁移ID、Up()/Down()方法代码必须完全相同); - 在App启动时,先检查
Db2.db的__EFMigrationsHistory表,如果没有MyFirstMigration的记录,手动插入一条(迁移ID要和旧项目的一致); - 再执行
Migrate(),EF会认为该迁移已经完成,不会再触发冲突; - 同样需要执行前面提到的Db1到Db2的数据迁移步骤。
总的来说,直接复制旧Migrations文件夹是最省心的方式,能从根源上避免迁移历史不匹配的问题,同时配合数据迁移逻辑,就能完美兼顾新老用户的需求。
内容的提问来源于stack exchange,提问作者Muhammad Touseef
相关产品推荐
相关产品推荐

