通过控制台应用程序创建/更新数据库架构

时间:2020-02-03 01:57:00

标签: c# .net-core entity-framework-core .net-core-3.0

我有一个控制台应用程序,该应用程序使用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命令行进行迁移。我更喜欢用代码来处理它。

2 个答案:

答案 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)

还可以使用employeeclass constructor

来创建和object initializer
相关问题