EFコアにIModelCacheKeyFactoryを実装する方法

entity-framework-core schema

質問

ストーリー:マルチテナントアプリケーション(1つのPostgreSQLDB、複数のスキーマ)では、複数のスキーマに対して1つのDbContextを使用する必要があります。

私が試したこと:キャッシュを保持する(Dictionary、keyはスキーマ名、valueはそのスキーマのコンテキスト)別のスキーマに新しいコンテキストを導入すると、dbContextスキーマはまだ提供されている以前のスキーマに設定されていることがわかります。私は、コンテキスト内のモデルが内部的にコンテキストタイプによってキャッシュされていると仮定します。

上のように動作していないようで、私はIModelCacheKeyFactoryの実装がそのトリックを行うべきであることを発見しました。誰もがCreateメソッドに入るべきだと知っていますか?どこにもサンプルもドキュメンテーションもありません。

私が見つけたもの: Entity Framework Coreのスキーマを動的に変更していますが、EF6には答えます。

受け入れられた回答

次に例を示します。

class MyDbContext : DbContext
{
    public MyDbContext(string schema)
    {
        Schema = schema;
    }

    public string Schema { get; }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options
            .UseSqlServer("...")
            .ReplaceService<IModelCacheKeyFactory, MyModelCacheKeyFactory>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema(Schema);

        // ...
    }
}

class MyModelCacheKeyFactory : IModelCacheKeyFactory
{
    public object Create(DbContext context)
        => new MyModelCacheKey(context);
}

class MyModelCacheKey : ModelCacheKey
{
    string _schema;

    public MyModelCacheKey(DbContext context)
        : base(context)
    {
        _schema = (context as MyDbContext)?.Schema;
    }

    protected override bool Equals(ModelCacheKey other)
        => base.Equals(other)
            && (other as MyModelCacheKey)?._schema == _schema;

    public override int GetHashCode()
    {
        var hashCode = base.GetHashCode() * 397;
        if (_schema != null)
        {
            hashCode ^= _schema.GetHashCode();
        }

        return hashCode;
    }
}


Related

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