来自Microsoft Store的 WinUI 3 MSIX应用无法创建SQLite数据表,但在调试或本地构建时可以正常工作

编程语言 2026-07-09

我有一个WinUI 3 / .NET 8应用打包为MSIX,并通过Microsoft Store发布。

该应用使用EF Core 8与 SQLite。启动时我通过迁移初始化数据库:

using var db = Services
    .GetRequiredService<IDbContextFactory<AppDbContext>>()
    .CreateDbContext();

DatabaseMigrationService.Migrate(db);

本地从Visual Studio / Debug运行时应用工作正常。然而,在安装了Microsoft Store版本后,一些页面保持空白或加载数据失败。在1.1.0.0版本中,任务页面卡在加载指示器上。加入try/finally包围加载逻辑后,加载指示器消失,但数据库似乎仍然缺少表,添加新任务也失败。

应用把错误写入 errors.log。从商店安装的版本我得到:

[2026-05-31 16:38:35] Unhandled: SQLite Error 1: 'no such table: pomodoro_table'.
[2026-05-31 16:38:35] Unhandled: SQLite Error 1: 'no such table: pomodoro_table'.
[2026-05-31 16:38:35] Unhandled: SQLite Error 1: 'no such table: task_table'.

在之后的商店更新之后:

[2026-05-31 23:53:46] Unhandled: SQLite Error 1: 'no such table: pomodoro_table'.
[2026-05-31 23:53:46] Unhandled: SQLite Error 1: 'no such table: pomodoro_table'.
[2026-05-31 23:53:49] Unhandled: An error occurred while saving the entity changes. See the inner exception for details.

我的项目文件在非调试构建中开启了修剪:

<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>

我怀疑Microsoft Store / Release MSIX构建的行为有所不同,因为 PublishTrimmed=True,并且EF Core的迁移可能并非完全对修剪安全。

在最新尝试修复之前相关的迁移启动代码:

public static void Migrate(AppDbContext db)
{
    var connection = db.Database.GetDbConnection();
    db.Database.OpenConnection();

    try
    {
        if (TableExists(connection, "task_table"))
        {
            EnsureHistoryTable(connection);
            EnsureLegacySchema(connection);
            EnsureBaselineHistory(connection);

            if (ColumnExists(connection, "pomodoro_table", "pomodoro_review"))
                EnsureMigrationHistory(connection, PomodoroReviewMigrationId);
        }

        db.Database.Migrate();
    }
    finally
    {
        db.Database.CloseConnection();
    }
}

问题在于从商店安装后,看起来 db.Database.Migrate() 要么失败,要么在没有创建预期表的情况下完成。应用随后继续运行,后续查询因为没有这样的表而失败。

问题

  1. PublishTrimmed=True 是否会破坏WinUI 3的 MSIX应用中EF Core SQLite的迁移?
  2. EF Core的修剪是否应在商店/发布构建中禁用?
  3. 在打包的WinUI 3应用中,是否有推荐的初始化或修复EF Core SQLite数据库的方法?
  4. 我应该使用 Database.Migrate()EnsureCreated(),还是为此类打包应用使用手动架构回退?

我考虑把项目改为:

<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">False</PublishTrimmed>

并添加一个迁移后架构验证/回退,当 Migrate() 不存在时创建缺失的表。

这是正确的做法吗,还是有更适合商店安全的方式来处理WinUI 3中的EF Core SQLite迁移?

解决方案

我找到了并解决了这个问题(感谢在我的问题下的有益评论)。

SQLite文件在应用的LocalState文件夹中已正确创建,因此这不是文件路径或权限问题。

当我检查由Microsoft Store版本创建的损坏数据库时,数据库文件是有效的:

PRAGMA quick_check = ok

但架构不完整。里面唯一的表是:

__EFMigrationsHistory

并且没有任何行。应用程序表丢失:

task_table
pomodoro_table
note_table
todo_table

原因在于我的Release/MSIX发布配置。 我开启了修剪:

<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>

这与EF Core 8的运行时迁移是一个糟糕的组合。EF Core在运行时元数据/反射方面高度依赖,修剪可能会移除运行时需要的内容。我的调试/本地构建之所以能工作,是因为它们使用的商店包并未进行同样的修剪。

修复方法是:

1.为 Store/Release包禁用修剪:

<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">False</PublishTrimmed>

2.在启动迁移后添加一个防御性架构验证步骤:

我在启动迁移后添加了一个防御性的架构验证/修复步骤。之前应用程序基本上信任EF的迁移。现在,在打开数据库并运行迁移后,应用会显式地验证所需表是否存在,如缺失则创建/修复架构。

概念上:

using var db = dbContextFactory.CreateDbContext();

try
{
    db.Database.Migrate();

    // New: do not trust that Migrate() actually produced a complete schema.
    EnsureCurrentSchema(db.Database.GetDbConnection());
}
catch
{
    // New: if migration fails, still try to create/repair the required SQLite schema.
    EnsureCurrentSchema(db.Database.GetDbConnection());
    throw;
}

EnsureCurrentSchema会检查/创建所需的SQLite表,如task_table、pomodoro_table、note_table和 todo_table,并确保迁移历史基线存在。

这很重要,因为损坏的Store版本已经创建了一个仅包含 __EFMigrationsHistory而没有应用程序表的有效SQLite文件。普通的全新数据库检查并不足以解决问题;应用还必须处理“数据库文件存在但架构不完整”的情况。

将此修复作为1.1.2版本发布后,我测试了两种情况:

  1. 更新损坏的Microsoft Store版本。
  2. 从Microsoft Store卸载并重新安装。

两种情况现在都能正确工作。应用会创建数据库架构,任务页面不再卡住或因以下错误失败:

SQLite Error 1: 'no such table: pomodoro_table'
SQLite Error 1: 'no such table: task_table'

因此最后的教训是:如果你在WinUI 3/MSIX Store应用中使用EF Core的运行时迁移,请对PublishTrimmed非常小心。同时记录并验证实际的SQLite数据库路径和架构,而不仅仅是.db文件是否存在。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章