我有一个控制台应用程序,该应用程序使用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 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命令行进行迁移。我更喜欢用代码来处理它。
答案 0 :(得分:1)
在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
,因此实体框架命令行工具可以在创建迁移时发现任何自定义配置。
答案 1 :(得分:0)
还可以使用employee
或class constructor
object initializer