為Entity Framework Core中的所有數據庫創建和應用遷移

c# ef-migrations entity-framework entity-framework-core migration

我有ApplicationDbContext ,它動態地將連接字符串更改為數據庫,這取決於用戶的庫名。所以,對於每個庫,我都擁有自己的數據庫。當我創建遷移並應用它們時,它們僅與具有默認連接字符串的默認數據庫相關,其中未定義庫名稱。

如何創建和應用遷移到動態創建的所有數據庫,這些數據庫取決於庫名稱(它們在創建後存在,它們是完全定義的和工作數據庫)?

一般承認的答案

如果我理解你,你應該實現以下內容:

1)實現將遷移模式和種子數據的服務。 (儘管他們在最新版本中做了什麼,我仍然更喜歡我的實現)

幫手

    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接口

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

種子服務實施

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文件

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)在DI中註冊上下文和相關服務,這將允許動態檢索連接字符串。有幾種方法可以做到,我的實現並不是最好的,所以這取決於你。

Startup.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文件。

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"];

我希望它對你有所幫助。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow