You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MAUI Blazor Hybrid中修改DbContext后更新SQLite数据库

解决MAUI Blazor Hybrid中EF Core SQLite数据库架构同步问题

核心问题分析

问题出在三个关键点:

  • EnsureCreated() 仅在数据库不存在时创建新库表,不处理架构更新,也不会生成EF Core的迁移历史表(__EFMigrationsHistory)。
  • Migrate() 依赖预先生成的迁移文件才能生效,你之前未生成迁移文件,调用后自然无效果。
  • 数据库路径配置错误(代码中写的databse.db拼写错误),导致EF Core可能找不到现有旧数据库,无法执行迁移逻辑。

解决步骤

1. 修正DbContext的DI注入配置

在MauiProgram.cs中替换原有的AddDbContext配置,明确指定SQLite连接字符串,并使用MAUI平台特定的存储路径(避免跨平台路径不一致问题):

using BAL;
using DAL;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.IO;

namespace Bitacora
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });

            builder.Services.AddMauiBlazorWebView();

            // 配置DbContext,使用正确的平台存储路径
            builder.Services.AddDbContext<BitacoraContext>(options =>
            {
                var dbPath = Path.Combine(FileSystem.AppDataDirectory, "database.db");
                options.UseSqlite($"Data Source={dbPath}");
            });

            builder.Services.AddTransient<ServiceTareas>();
            builder.Services.AddTransient<ServiceRevisiones>();

#if DEBUG
            builder.Services.AddBlazorWebViewDeveloperTools();
            builder.Logging.AddDebug();
#endif

            // 应用启动时自动执行数据库迁移
            var app = builder.Build();
            using (var scope = app.Services.CreateScope())
            {
                var dbContext = scope.ServiceProvider.GetRequiredService<BitacoraContext>();
                dbContext.Database.Migrate();
            }

            return app;
        }
    }
}

2. 清理DbContext构造函数中的冲突代码

修改BitacoraContext.cs,删除构造函数中的Database.EnsureCreated();,避免和Migrate()逻辑冲突:

public class BitacoraContext : DbContext
{
    public DbSet<AreaTarea> AreasTareas { get; set; }
    public DbSet<Area> Areas { get; set; }
    public DbSet<SucursalTab> SucursalTabs { get; set; }
    public DbSet<Revision> Revisiones { get; set; }
    public DbSet<RevisionTarea> RevisionesTareas { get; set; }

    public BitacoraContext(DbContextOptions<BitacoraContext> options) : base(options)
    {
        // 移除EnsureCreated,改用启动时的Migrate逻辑
    }

    // 保留原有OnModelCreating实体配置代码
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SucursalTab>(entity =>
        {
            entity.ToTable("SucursalesTabs");
            entity.HasKey(c => c.Id);
            entity.Property(c => c.Id).IsRequired().ValueGeneratedOnAdd();

            entity.HasMany(a => a.Areas).WithOne(t => t.SucursalTab)
                .HasForeignKey(t => t.TabId);
        });

        // 其他实体配置代码...

        base.OnModelCreating(modelBuilder);
    }
}

3. 生成与管理迁移文件

迁移文件是EF Core记录架构变更的核心,每次修改DbContext后都需生成新迁移:

安装EF Core工具(未安装时执行)
dotnet tool install --global dotnet-ef
生成初始迁移

进入项目根目录(包含.csproj文件的文件夹),执行:

dotnet ef migrations add InitialCreate

此命令会生成Migrations文件夹,包含初始数据库架构的迁移代码。

后续架构变更时生成新迁移

比如新增表或修改字段后,执行:

dotnet ef migrations add Add[变更描述]
# 示例:新增User表时执行 dotnet ef migrations add AddUserTable

4. 适配已有旧数据库

如果已有用户使用旧版本应用(通过EnsureCreated()创建的数据库),这类数据库没有__EFMigrationsHistory表,需手动标记初始迁移为已应用:

  1. 生成初始迁移的SQL脚本:
dotnet ef migrations script InitialCreate -o initial.sql
  1. 打开initial.sql,找到类似如下的行:
INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20240520123456_InitialCreate', '8.0.5');
  1. 将该行SQL执行到用户的现有数据库中(可通过应用启动代码自动检测执行,或手动处理),之后Migrate()就能识别现有架构并应用后续迁移。

注意事项

  • 禁止同时使用EnsureCreated()和Migrate(),二者逻辑互斥。
  • 迁移文件需随应用代码一同发布,确保更新时能执行。
  • 测试阶段可清空测试设备数据库,验证迁移流程是否正常。

内容的提问来源于stack exchange,提问作者FernanOwO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 00:28:14