uwp sqlite add-migration 在更新到新项目时崩溃

uwp sqlite add-migration crashes when updated to a new project

根据 this documentation.

,我的 uwp 项目(entity framework)中有 SQLite 数据库

我有一个针对 周年更新 的 uwp 项目,所以当时这个文档很旧,我不得不在我的 uwp 项目中添加数据库代码和东西(而不是在.Net 标准项目),所以很多用户在商店安装了这个项目,他们现在显然都在他们的设备上创建了一个数据库,比方说 Db1.db.

一年后,我更新了我的应用程序并将其重新定位到创作者更新,我在一个新项目中这样做了,因为我必须对我的应用程序进行一些重大更改,所以我想从一个干净的项目开始,我添加了我的功能,并以与之前项目相同的方式添加数据库内容,具有相同的数据库名称Db1.db,然后我也将其发布到商店。

问题

现在,当我发布我的第二个包时,它在 DBContext.Migrate() 方法上崩溃了,该方法应该在 [=70= 的构造函数中] 我知道它崩溃是因为数据库的名称相同并且两个项目只有一个迁移称为 MyFirstMigration 并且不知何故冲突并导致应用程序崩溃。我可以确认这一点,因为在我更新我的第二个包(针对创建者更新)并将数据库名称更改为 Db2.db 之后不久,现在我没有得到崩溃,因为现在应用程序忽略了用户设备上的旧数据库,只是创建和使用新数据库,这不是最好的方法,因为我现有的用户无法访问他们在 Db1[=49 中的数据=] 尽管新用户不会受到影响,因为他们的所有数据都只在 Db2.

现在的情况是这样的:

用户组 1 这些用户的旧数据在 db1 中,新数据在 db2

用户组 2 这些用户的所有数据都在 db2

我可能会继续从头开始创建新项目以针对更新的 SDK,因为我喜欢从头开始进行更新的主要更新,这有助于我轻松地重构整个应用程序。那么如何在不使应用程序崩溃的情况下在我的新项目中使用相同的数据库名称呢?我不会更改我的模型,我的模型将保持不变,并且无论我向商店发布多少新项目,我都想继续只使用 1 个数据库文件,应用程序应始终与该 1 个数据库文件通信。如果我只是从我的旧项目复制 Migrations 文件夹并将其粘贴到新项目并使该迁移文件夹在我的新版本中保持一致,这是否可能?或者还有其他方法吗?

另请注意,现在在我的新项目中,我的最低目标将是秋季创作者更新,因此我将使用 .net 标准库将我的数据库内容保存在上面提到的文档中,所以我想在我的新项目中也继续使用 db2.db

这似乎是关于用户数据同步的问题。据我了解,您可以在新的秋季创作者更新 UWP 应用程序(我们称之为新版本)中使用 db2.db,但是在用户将您的应用程序升级到新版本后并在第一次启动你的应用程序时,你可以检查你的项目中是否存在db1.db,如果存在,你可以从[=40=中复制数据]db1.db到新的db2.db

这种方式貌似是备份恢复,但是在uwp app中,update不会删除你的db1.db,你只需要"restore"或者将数据复制到使用EF Core UWP应用程序新功能创建的新db2.db,然后您可以直接操作db2.db以后存储用户数据,您不再需要再次使用db1.db

---更新---

are you saing everytime I create a new project I should copy data from previous database? means I cannot use same database file?

实际上,您只需要从 db1.db 复制一次到 db2.db,因为您已经将项目转换为使用 EF Core。在以后的版本中,由于你已经使用了EF Core,如果你新建一个项目更新,你可以直接使用db2.db,我的测试是没有问题的。

how can I check if old db exists?

由于知道了db文件名和文件位置,可以通过检查db文件是否存在来判断旧的db是否存在

private async Task<bool> IsFileExisted(string fileName)
{
    var result= await ApplicationData.Current.LocalFolder.TryGetItemAsync(fileName);
    if (result == null)
    {
        return false;
    }
    return true;
}

由于您提供的document,似乎在应用程序的构造函数中调用了Migrate方法,这将导致难以使用异步方法。所以你可以把Migrate的代码放在App的OnLaunched事件处理器中。

 protected async override void OnLaunched(LaunchActivatedEventArgs e)
 {
     using (var db = new BloggingContext())
     {
         //db.Database.EnsureCreated();
         bool isExist = await IsFileExisted("db1.db");
         if (!isExist)
         {
             db.Database.Migrate();
         }

     }

     Frame rootFrame = Window.Current.Content as Frame;

     // Do not repeat app initialization when the Window already has content,
     // just ensure that the window is active
     if (rootFrame == null)
     {
         // Create a Frame to act as the navigation context and navigate to the first page
         rootFrame = new Frame();

         rootFrame.NavigationFailed += OnNavigationFailed;

         if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
         {
             //TODO: Load state from previously suspended application
         }

         // Place the frame in the current Window
         Window.Current.Content = rootFrame;
     }

     ...
}

如果您使用此方案,则无需创建 db2.db,只需在新版本项目中使用 db1.db。

right now my latest project uses db2 so can I connect to db1 from this project without calling migrate function? (because migrate function crashes the app.) and then just copy data from db1 to db2.

迁移函数将上下文的任何未决迁移应用到数据库,如果数据库尚不存在,将创建该数据库。如果数据库不存在,则需要使用 migrate 函数创建数据库。当然,如果db1.db存在,可以不调用migrate函数直接连接db1获取数据

要实现的话,可以按照document在模型库中创建一个NewBloggingContext class继承DbContext连接到db1.db并复制数据。