简体   繁体   English

为 Entity Framework Core 中的所有数据库创建和应用迁移

[英]Create and apply migrations for all databases in Entity Framework Core

I have ApplicationDbContext , which dynamically change connection string to database, which depends on user's library name.我有ApplicationDbContext ,它动态地将连接字符串更改为数据库,这取决于用户的库名称。 So, for each library, I have it's own database.所以,对于每个图书馆,我都有自己的数据库。 When I'm creating migrations and apply them, they are related only to default database with default connection string, where no library name defined.当我创建迁移并应用它们时,它们仅与具有默认连接字符串的默认数据库相关,其中没有定义库名称。

How can I make and apply migrations to all this databases, that dynamically created, that depends on library name (they exist after creation, they are fully defined and working databases)?我如何对所有这些动态创建的数据库进行迁移并将其应用到依赖于库名称的数据库(它们在创建后存在,它们是完全定义和工作的数据库)?

If I understood you properly, you should implement the following:如果我理解正确,您应该执行以下操作:

1) Implement Service that will migrate your schema and seed data. 1) 实施将迁移您的架构和种子数据的服务。 (despite what they did in the latest version , I still prefer my implementation) (尽管他们在最新版本中做了什么,我仍然更喜欢我的实现)

Helper帮手

    public static async Task EnsureSeedData(IServiceProvider serviceProvider)
    {
        using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            // here could be several seed services if necessary
            var seedService = scope.ServiceProvider.GetService<ISeedService>();
            await seedService.MigrateAsync();
            await seedService.SeedAsync();
        }
    }

ISeedService Interface种子服务接口

internal interface ISeedService
{
    Task MigrateAsync();
    Task SeedAsync();
}

SeedService Implementation种子服务实现

internal sealed class SeedService : ISeedService
{
    private readonly InitializeContext _identityContext;

    public SeedService(InitializeContext identityContext)
    {
        _identityContext = identityContext;
    }

    public async Task MigrateAsync()
    {
        await _identityContext.Database.MigrateAsync();
    }

    public async Task SeedAsync()
    {
        if (_identityContext.AllMigrationsApplied())
        {
            var strategy = _identityContext.Database.CreateExecutionStrategy();
            await strategy.ExecuteAsync(async () =>
            {
                using (var transaction = await _identityContext.Database.BeginTransactionAsync())
                {
                    // seed data if necessary
                    transaction.Commit();
                }
            });
        }
    }
}

Program.cs file程序.cs文件

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();
        Task.Run(async () =>
        {
            await SeedData.EnsureSeedData(host.Services);
        }).Wait();
        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

2) Register context and related services in DI, which will allow dynamically retrieve connection string. 2) 在 DI 中注册上下文和相关服务,这将允许动态检索连接字符串。 There are several ways to do it, my implementation is not the best one, so it's up to you.有几种方法可以做到,我的实现不是最好的,所以这取决于你。

Startup.cs file启动.cs文件

public class Startup
{
    public IConfiguration Configuration { get; }
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<ISeedService, SeedService>();
        services.AddScoped<IDbConfiguration, FakeDbConfiguration>();
        services.AddDbContext<InitializeContext>((provider, builder) =>
        {
            var dbConfiguration = provider.GetService<IDbConfiguration>();
            builder.UseSqlServer(dbConfiguration.Connection);
        });

        // omitted
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // omitted
    }
}

DbConfiguration file. Db 配置文件。

internal sealed class FakeDbConfiguration : IDbConfiguration
{
    private readonly IConfiguration _configuration;
    public FakeDbConfiguration(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    // REPLACE THIS PART WITH YOURS IMPLEMENTATION
    public string Connection => _configuration["Database:Connection"];

I hope it help you.我希望它能帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 多个数据库上的 Entity Framework Core 迁移 - Entity Framework Core migrations on multiple databases 实体框架,自动应用迁移 - Entity Framework, Automatic apply Migrations 实体框架在运行时应用迁移 - Entity Framework apply migrations at runtime 实体框架核心:创建合并多个DbContexts的迁移(具有多个迁移) - Entity Framework Core: create a migration that merges multiple DbContexts (with multiple migrations) 测试实体框架核心迁移 - Testing Entity Framework Core Migrations 使用迁移与实体框架核心 - Using Migrations with Entity Framework Core 实体框架代码首先迁移多个数据库 - Entity Framework code first migrations with multiple databases 如何在同一项目中使用 2 个不同的数据库架构组织 Entity Framework Core 迁移(代码优先)? - How to organize Entity Framework Core migrations (code first) with 2 different databases schema in the same project? 在运行时在 .Net Core 中创建和应用迁移 - Entity Framework Core - Create and Apply Migration at run time in .Net Core - Entity Framework Core 在 Docker 映像中使用 ASP.Net Core 时应用实体框架迁移 - Apply Entity Framework migrations when using ASP.Net Core in a Docker image
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM