数据库文件无法正确重置,除非重新启动应用程序

问题描述 投票:0回答:1

我正在创建一个 .NET MAUI Android 应用程序,它使用内置的本地 SQLite 数据库文件、CommunityMVVMToolKit 只是因为它很棒,而 EntityFramework Core 用于将对象映射到数据库记录,反之亦然。

我是这个框架的新手,并且不确定应该如何处理数据库文件,我决定将一个包含所有表模式的新数据库放在

Resources/Raw
文件夹中,并且没有记录作为原始资源。启动后,应用程序会检查数据库文件应存在的预定位置,如果不存在,则会在所述位置创建新数据库文件的副本。原因是(据我在互联网上找到的)与应用程序捆绑的资产是只读的,包括数据库文件,因此必须将它们提取出来才能修改。

应用程序与文件通信良好,其中的数据在应用程序启动之间保留下来,但在尝试实现重置功能时遇到了一个小问题。

我编写了下面的代码片段用于测试目的,看看

DatabaseFile
方法是否正常工作:

[RelayCommand]
void PerformDatabaseFileTests()
{
    ClearText();
    try
    {
        //After starting the app the DB should already be there, check for it
        AppendText($"DATABASE FILE EXISTS: {DatabaseFile.Exists()}");

        //Delete it and check if it deleted
        AppendText("DELETING DB FILE...");
        DatabaseFile.Delete();
        AppendText($"DATABASE FILE EXISTS: {DatabaseFile.Exists()}");

        //Create it again
        AppendText("CREATING DB FILE...");
        MainThread.InvokeOnMainThreadAsync(DatabaseFile.Create);
        AppendText($"DATABASE FILE EXISTS: {DatabaseFile.Exists()}");
    }
    catch (Exception ex)
    {
        AppendText("EXCEPTION WAS THROWN!");
        AppendText(ex.ToString());
        AppendText(ex.Message);
    }
}

调试页面视图模型中包含的此方法执行以下操作:

  • 检查该位置是否存在数据库文件

  • 尝试删除DB文件并检查是否存在

  • 创建一个新副本并检查它是否存在

言归正传,问题是当我修改数据库中的记录(添加、更新、删除)时,执行上述DB文件测试方法并尝试读取数据库文件的内容,修改仍然存在。在一个应该被删除并从新模板文件重建的文件中。

底层

File.Exists()
方法确实报告数据库文件在删除之前存在,删除后不存在,创建后又存在。

另外,值得一提的是,执行数据库文件测试方法,关闭应用程序然后重新打开而不查询任何数据,似乎可以正确重置数据库文件。虽然此解决方法确实有效,但我真的希望无需重新启动应用程序即可完成重置。

以下是DatabaseFile类的内容:

public static class DatabaseFile 
{ 
    public static string FullPath => 
        Path.Combine(FileSystem.Current.AppDataDirectory, Filename);  
  
    public static async Task Create()
    {
        using Stream inputStream = await FileSystem.Current.OpenAppPackageFileAsync(Filename);
        using FileStream outputStream = File.Create(FullPath);
        await inputStream.CopyToAsync(outputStream);
    }
    public static void Delete()
    {
        if (Exists()) 
            File.Delete(FullPath);
    }
    public static bool Exists() =>
        File.Exists(FullPath);
}

也许数据库文件根本不应该像任何其他 MauiAsset 一样处理。有没有更好的方法来发布带有内置本地数据库的 Android 应用程序?

编辑: 每次创建新的 DbContext 实例时,都会建立与我的数据库文件的连接。以下是我的 DatabaseContext 类中的

OnConfiguring()
方法的内容,该方法派生了 DbContext:

public partial class DatabaseContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            SqliteConnectionStringBuilder builder = new SqliteConnectionStringBuilder()
            {
                DataSource = Path.Combine(FileSystem.Current.AppDataDirectory, DatabaseFile.Filename),
                Mode = SqliteOpenMode.ReadWriteCreate,
                ForeignKeys = true
            };
        optionsBuilder.UseSqlite(builder.ToString());
    }
}

我是否错误地假设在释放 DbContext 实例时连接会自动关闭?

c# android database maui file-handling
1个回答
0
投票

我搞砸了,终于找到了解决方案,这就是我所做的:

DatabaseFile.Delete
方法更改为以下内容:


    公共静态异步任务删除()
    {
        使用 var context = new DatabaseContext();
        等待 context.Database.EnsureDeletedAsync();
    }

EnsureDeleted
是我一直在寻找的基本方法。为了确定起见,我还将
DatabaseFile.Delete
方法更改为异步方法并在调用时等待。

执行稍微改变的测试方法后,修改不再保留在新数据库中。该方法唯一的变化是等待

DatabaseFile.Delete
方法:


    AppendText("正在删除数据库文件...");
    等待DatabaseFile.Delete();
    AppendText($"数据库文件存在:{DatabaseFile.Exists()}");

© www.soinside.com 2019 - 2024. All rights reserved.