在WPF中使用EFCore Migration

在WPF(.NET5)中使用EFCore进行数据迁移的障碍主要是EFCore无法创建DbContext,通过实现IDesignTimeDbContextFactory接口可以通过自主创建DbContext,解决EFCore找不到数据库上下文的问题。

参考资料:WPF with entity framework on net core - unable to create and object of type AppDbContext

本文的环境为:WPF + .NET5 + EF Core + SQLite。

1、DesignTimeDbContextFactory

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<SqliteDbContext>
{
    public SqliteDbContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<SqliteDbContext>();
        optionsBuilder.UseSqlite("Data Source=Data.db");
        return new SqliteDbContext(optionsBuilder.Options, null);
    }
}

2、SqliteDbContext

public class SqliteDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<UserRole> UserRoles { get; set; }

    private readonly string _connectionString;

    // ReSharper disable once IdentifierTypo
    public SqliteDbContext(DbContextOptions<SqliteDbContext> options, IConfigService configService)
        : base(options)
    {
        _connectionString = configService?.SqliteConnectionString;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!string.IsNullOrWhiteSpace(_connectionString))
        {
            optionsBuilder.UseSqlite(_connectionString);
        }

        optionsBuilder.UseLazyLoadingProxies();

        base.OnConfiguring(optionsBuilder);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //添加角色
        modelBuilder.Entity<UserRole>().HasData(
            new UserRole() {Id = 1, Name = @"user", Remark = @"普通用户"},
            new UserRole() {Id = 2, Name = @"admin", Remark = @"管理员"}
        );

        //添加用户
        modelBuilder.Entity<User>().HasData(
            new User()
            {
                Id = 1, UserName = @"test", Password = @"123456", CreateTime = DateTime.Now, UserRoleId = 1
            },
            new User()
            {
                Id = 2, UserName = @"admin", Password = @"123456", CreateTime = DateTime.Now, UserRoleId = 2
            }
        );
    }
}

3、注意事项

(1)IDesignTimeDbContextFactory接口的泛型必须是已定义的DbContext(比如文中的SqliteDbContext)。

(2)optionsBuilder.UseSqlite中的连接字符串必须明确定义,这里定义为常量,也可以是从配置中加载的字符串。使用其他数据库,例如MySQL,也是一样的。

(3)进行数据迁移的时候要确保安装这些包:Microsoft.EntityFrameworkCore、Microsoft.EntityFrameworkCore.Sqlite、Microsoft.EntityFrameworkCore.Tools。

4、常用数据迁移命令

可以在程序包管理器控制台上执行数据迁移命令,当然也可以直接在命令行中执行。

(1)配置Migration

Enable-Migrations -ContextTypeName "TestWpf.SqliteDbContext" -ProjectName " TestWpf" -StartUpProjectName " TestWpf" -ConnectionStringName "Data Source=Data.db" -Verbose

(2)添加数据迁移

add-migration InitialMigration -Context LabelPrintingSystem.Database.SqliteDbContext

(3)更新数据库

update-database
posted @ 2021-08-17 19:41  xhubobo  阅读(894)  评论(0编辑  收藏  举报