如何在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表,需手动标记初始迁移为已应用:
- 生成初始迁移的SQL脚本:
dotnet ef migrations script InitialCreate -o initial.sql
- 打开
initial.sql,找到类似如下的行:
INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") VALUES ('20240520123456_InitialCreate', '8.0.5');
- 将该行SQL执行到用户的现有数据库中(可通过应用启动代码自动检测执行,或手动处理),之后
Migrate()就能识别现有架构并应用后续迁移。
注意事项
- 禁止同时使用
EnsureCreated()和Migrate(),二者逻辑互斥。 - 迁移文件需随应用代码一同发布,确保更新时能执行。
- 测试阶段可清空测试设备数据库,验证迁移流程是否正常。
内容的提问来源于stack exchange,提问作者FernanOwO
相关产品推荐
相关产品推荐

