1

私のカスタム IDbContextFactory 実装を以下に示します。私のリポジトリでは、このファクトリのインスタンスを作成します。マルチテナント アプリを実行しているため (各テナントには独自のデータベースがあります)、DbContext を作成できるように ConnectionString および Tenant プロパティも設定する必要があります。

データベースが存在しない場合、これはすべてうまく機能しますが、移行を実行する必要がある場合、DbMigrationsConfiguration はこのファクトリを使用して EFDbContext のインスタンスを作成しようとしますが、もちろん ConnectionString と Tenant が設定されていないため失敗します。

この問題を回避するための別の戦略を持っている人はいますか?

public class DbContextFactory : IDbContextFactory<EFDbContext>
{
    public string ConnectionString { get; set; }
    public string Tenant { get; set; }

    public EFDbContext Create()
    {
        var connectionInfo = new DbConnectionInfo(ConnectionString, "System.Data.SqlClient");

        if (EFContextHelper.Contexts.Contains(Tenant))
        {
            return new EFDbContext(ConnectionString, Tenant);
        }
        else
        {
            EFDbContext context = new EFDbContext(ConnectionString, Tenant);

            if (!context.Database.Exists())
            {
                Database.SetInitializer<EFDbContext>(new EFDbContextInitializer());
                context.Database.Initialize(false);
            }
            else
            {
                bool doMigration = false;
                try
                {
                    doMigration = !context.Database.CompatibleWithModel(true);
                }
                catch (NotSupportedException)
                {
                    // no metadata for migration
                    doMigration = true;
                }

                // not working cause migrator is trying to instantiate this factory without setting connection string etc
                if (doMigration)
                {
                    var migrationConfig = new DbMigrationsConfiguration<EFDbContext>(); 
                    migrationConfig.AutomaticMigrationDataLossAllowed = false;
                    migrationConfig.AutomaticMigrationsEnabled = true;
                    migrationConfig.TargetDatabase = connectionInfo;
                    var migrator = new DbMigrator(migrationConfig);
                    migrator.Update();
                }
            }

            EFContextHelper.Contexts.Add(Tenant);

            return context as EFDbContext;
        }
    }

ありがとう、ゲイリー

4

1 に答える 1

2

私はこの問題を自分で解決することができました。私は応答を受け取っていないので、この問題に遭遇した他の人のためにここに残します.

基本的に、DbContext クラスのインスタンス化を次のように調整しました。

public EFDbContext(string connectionString, string tenant) : base(connectionString ?? "EFDBContext")
{
     Tenant = tenant;
}

したがって、この場合、渡された接続文字列が空の場合、デフォルトで設定ファイルの接続文字列名になります。マイグレーターは、割り当てられた接続を保持しているように見えます:

migrationConfig.TargetDatabase = connectionInfo;

これが誰かに役立つことを願っています。

于 2013-03-20T08:42:34.253 に答える