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();
}

SeedServiceの実装

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
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ