Creating/Updating 来自控制台应用程序的数据库架构
Creating/Updating database schema from a console application
我有一个控制台应用程序,它使用 EF 与后端数据库进行交互。核。我有如下所示的 DBContext。
class HRDepartmentContext : DbContext
{
public DbSet<Employee> Employee { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=somepath\employees.db");
}
它在 class 中消耗,如下所示。
class EmployeeManager
{
public CreateEmployee(string firstname, string lastname)
{
using (var db = new EmployeeContext())
{
db.Database.EnsureCreated();
// logic for employee creation
}
}
// other methods for delete/update the employees
public UpdateEmployee(...) {...}
public DeleteEmployee(...) {...}
}
我的问题。
a) 调用 EnsureCreated 方法的最佳方式是什么,因为我不想在单个 Create/Update/Delete Employee 方法中调用它。
b) 在应用程序的未来版本中处理架构更改场景的最佳方式是什么?阅读文档,看起来 EsureCreated 无法处理这种情况。显然需要在不丢失任何现有数据的情况下执行升级模式。
更新:
我想避免在架构更改时使用任何 EF 命令行进行迁移。我更喜欢代码来处理它。
也可以使用 class constructor
或 object initializer
创建 employee
就我个人而言,在 netcore 3 中,我会在您的控制台应用程序中使用通用 IHost
。然后使用依赖注入配置数据库服务。以及 IHostedService
在启动期间创建或迁移数据库。
public class Program {
public static void ConfigureServices(HostBuilderContext context, IServiceCollection serviceCollection)
{
serviceCollection.AddEntityFrameworkSqlite();
serviceCollection.AddHostedService<DatabaseStartup>();
serviceCollection.AddDbContextPool<HRDepartmentContext>(o =>
{
o.UseSqlite("Data Source=somepath\employees.db");
});
// configure other services here
}
public static async Task<int> Main(string[] args)
{
using (var host = CreateHostBuilder(args).Build())
{
await host.StartAsync();
var lifetime = host.Services.GetRequiredService<IHostApplicationLifetime>();
// insert other console app code here
lifetime.StopApplication();
await host.WaitForShutdownAsync();
}
return 0;
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host
.CreateDefaultBuilder(args)
.UseConsoleLifetime()
.ConfigureServices(ConfigureServices);
}
public class DatabaseStartup : IHostedService {
private readonly IServiceProvider serviceProvider;
public DatabaseStartup(IServiceProvider serviceProvider){
this.serviceProvider = serviceProvider;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
using (var scope = serviceProvider.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<HRDepartmentContext>();
await db.Database.EnsureCreated();
// or
await db.Database.MigrateAsync();
}
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
由于您的控制台应用程序有 CreateHostBuilder
,entity framework 命令行工具可以在创建迁移时发现任何自定义配置。
我有一个控制台应用程序,它使用 EF 与后端数据库进行交互。核。我有如下所示的 DBContext。
class HRDepartmentContext : DbContext
{
public DbSet<Employee> Employee { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=somepath\employees.db");
}
它在 class 中消耗,如下所示。
class EmployeeManager
{
public CreateEmployee(string firstname, string lastname)
{
using (var db = new EmployeeContext())
{
db.Database.EnsureCreated();
// logic for employee creation
}
}
// other methods for delete/update the employees
public UpdateEmployee(...) {...}
public DeleteEmployee(...) {...}
}
我的问题。
a) 调用 EnsureCreated 方法的最佳方式是什么,因为我不想在单个 Create/Update/Delete Employee 方法中调用它。
b) 在应用程序的未来版本中处理架构更改场景的最佳方式是什么?阅读文档,看起来 EsureCreated 无法处理这种情况。显然需要在不丢失任何现有数据的情况下执行升级模式。
更新: 我想避免在架构更改时使用任何 EF 命令行进行迁移。我更喜欢代码来处理它。
也可以使用 class constructor
或 object initializer
employee
就我个人而言,在 netcore 3 中,我会在您的控制台应用程序中使用通用 IHost
。然后使用依赖注入配置数据库服务。以及 IHostedService
在启动期间创建或迁移数据库。
public class Program {
public static void ConfigureServices(HostBuilderContext context, IServiceCollection serviceCollection)
{
serviceCollection.AddEntityFrameworkSqlite();
serviceCollection.AddHostedService<DatabaseStartup>();
serviceCollection.AddDbContextPool<HRDepartmentContext>(o =>
{
o.UseSqlite("Data Source=somepath\employees.db");
});
// configure other services here
}
public static async Task<int> Main(string[] args)
{
using (var host = CreateHostBuilder(args).Build())
{
await host.StartAsync();
var lifetime = host.Services.GetRequiredService<IHostApplicationLifetime>();
// insert other console app code here
lifetime.StopApplication();
await host.WaitForShutdownAsync();
}
return 0;
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host
.CreateDefaultBuilder(args)
.UseConsoleLifetime()
.ConfigureServices(ConfigureServices);
}
public class DatabaseStartup : IHostedService {
private readonly IServiceProvider serviceProvider;
public DatabaseStartup(IServiceProvider serviceProvider){
this.serviceProvider = serviceProvider;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
using (var scope = serviceProvider.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<HRDepartmentContext>();
await db.Database.EnsureCreated();
// or
await db.Database.MigrateAsync();
}
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
由于您的控制台应用程序有 CreateHostBuilder
,entity framework 命令行工具可以在创建迁移时发现任何自定义配置。