移行に依存性を注入することはできますか(EF-Coreコードの最初の移行を使用して)?

asp.net-core dependency-injection ef-migrations entity-framework entity-framework-core

質問

私はIConfigurationを(コンストラクタの)マイグレーションに注入しようとしましたが、例外があります: "このオブジェクトに対して定義されたパラメータのないコンストラクタはありません。"

任意の回避策?

受け入れられた回答

できません。移行はアプリケーションのコンテキスト外で実行できる必要があります。

Entity-frameworkコマンドラインツールはコードを分析しますが、startup.csクラスは実行しません。

またそれはお勧めできません。あなたの移行は単純明快で、何にも依存してはいけません。もしそうであれば、設定が足りないと本番環境でテーブルや列が足りなくなる可能性があるという重大な実行時の副作用につながる可能性があります。

追加アドバイス

それが多くの小さい/等しい/手動の変更を含むならば。最善の方法は、移行ファイルを生成することです。どうして?このようにして、移行は決定的になります。結果がどうなるかを知っています。あなたの移行の行が失敗した場合、それが単純で明白である理由はなぜそれがそして容易に(より)修正可能です。


人気のある回答

あなたがしたいことをする方法があります。私のシナリオでは、DbContextを通じて接続文字列内のデータベース名を使用したいと考えています。 EFコア2.1.1が使用されます。 コードはここから変更されています

カスタムMigrationsAssemblyサービスを作成する

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Internal;
using System;
using System.Reflection;

public class ContextAwareMigrationsAssembly : MigrationsAssembly
{
    private readonly DbContext context;

    public ContextAwareMigrationsAssembly(
        ICurrentDbContext currentContext,
        IDbContextOptions options,
        IMigrationsIdGenerator idGenerator,
        IDiagnosticsLogger<DbLoggerCategory.Migrations> logger) : base(currentContext, options, idGenerator, logger)
    {
        context = currentContext.Context;
    }

    /// <summary>
    /// Modified from http://weblogs.thinktecture.com/pawel/2018/06/entity-framework-core-changing-db-migration-schema-at-runtime.html
    /// </summary>
    /// <param name="migrationClass"></param>
    /// <param name="activeProvider"></param>
    /// <returns></returns>
    public override Migration CreateMigration(TypeInfo migrationClass, string activeProvider)
    {
        var hasCtorWithDbContext = migrationClass
                .GetConstructor(new[] { typeof(DbContext) }) != null;

        if (hasCtorWithDbContext)
        {
              var instance = (Migration)Activator.CreateInstance(migrationClass.AsType(), context);
              instance.ActiveProvider = activeProvider;
              return instance;
        }

        return base.CreateMigration(migrationClass, activeProvider);
    }
}

DbContext内のIMigrationAssemblyサービスをカスタムクラスに置き換えます

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.ReplaceService<IMigrationsAssembly, ContextAwareMigrationsAssembly>();
}

次に、移行にDbContextパラメータを追加できます。

public Migration20180801(DbContext context)
{
    DatabaseName = context.Database.GetDbConnection().Database;
}

あなたの場合は、すべてのDbContextリファレンスをIConfigurationと置き換え、 CreateMigrationオーバーライドの関連するインスタンスを置き換えることができます。



Related

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