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

时间:2018-05-15 17:57:49

标签: c# entity-framework sqlite uwp entity-framework-core-migrations

好的,所以我的 uwp 项目中有 sqlite 数据库(带有实体框架),根据此文档 https://docs.microsoft.com/en-us/ef/core/get-started/uwp/getting-started

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

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

问题

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

  

现在就是现在的情况。

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

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

  

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

另请注意,现在在我的新项目中,我的最小目标将是创建者更新,所以我将使用.net标准库来保存我的数据库内容,如上面提到的文档中所述,所以我想继续使用我的新项目中也有 db2.db 。谢谢你的阅读。

1 个答案:

答案 0 :(得分:1)

这似乎是关于用户数据同步的问题。据我所知,您可以在新的秋季创作者更新UWP应用程序中使用 db2.db (我们将其称为新版本),但在用户将应用程序升级到新版本并在以下位置启动应用程序之后第一次,你可以检查你的项目中是否存在 db1.db ,如果它存在,你可以将数据从 db1.db 复制到新的<强> db2.db 即可。

这种方式看起来像备份和还原,但在uwp应用中,更新不会删除 db1.db ,您只需要&#34;恢复&#34;或者将数据复制到使用EF Core UWP应用程序的新功能创建的新 db2.db ,然后您只需操作 db2.db 即可存储稍后用户数据,您不再需要再次使用 db1.db

<强> --- ---更新

  每次我创建一个新项目你是否应该从以前的数据库中复制数据?意味着我不能使用相同的数据库文件?

实际上,您只需要从db1.db复制一次到db2.db,因为您已将项目转换为使用EF Core。在更高版本中,由于您已使用EF Core,因此如果您创建新的项目更新,则可以直接使用db2.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,似乎在App的构造函数中调用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即可。

  

现在我的最新项目使用db2所以我可以从这个项目连接到db1而无需调用迁移功能吗? (因为迁移功能会崩溃应用程序。)然后只需将数据从db1复制到db2。

migrate功能将上下文的任何挂起的迁移应用于数据库,如果数据库尚不存在,则会创建数据库。如果数据库不存在,则需要使用migrate功能创建数据库。当然,如果db1.db存在,您可以连接到db1以获取数据而无需调用migrate函数。

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