同じ DbContext 型の複数のモデルを交互に使用するAlternating between multiple models with the same DbContext type

構築されたモデルでは、 OnModelCreating コンテキストのプロパティを使用して、モデルの構築方法を変更できます。The model built in OnModelCreating can use a property on the context to change how the model is built. たとえば、いくつかのプロパティに基づいてエンティティを異なる方法で構成するとします。For example, suppose you wanted to configure an entity differently based on some property:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    if (UseIntProperty)
    {
        modelBuilder.Entity<ConfigurableEntity>().Ignore(e => e.StringProperty);
    }
    else
    {
        modelBuilder.Entity<ConfigurableEntity>().Ignore(e => e.IntProperty);
    }
}

残念ながら、EF はモデルを構築して1回だけ実行するため、このコードはそのようには機能し OnModelCreating ません。そのため、パフォーマンス上の理由から結果がキャッシュされます。Unfortunately, this code wouldn't work as-is, since EF builds the model and runs OnModelCreating only once, caching the result for performance reasons. ただし、モデルキャッシュメカニズムにフックして、さまざまなモデルを生成するプロパティを EF に認識させることができます。However, you can hook into the model caching mechanism to make EF aware of the property producing different models.

IModelCacheKeyFactoryIModelCacheKeyFactory

EF は、を使用して IModelCacheKeyFactory モデルのキャッシュキーを生成します。既定では、ef は、特定のコンテキスト型のモデルが同じであることを前提としています。したがって、このサービスの既定の実装では、コンテキスト型のみを含むキーが返されます。EF uses the IModelCacheKeyFactory to generate cache keys for models; by default, EF assumes that for any given context type the model will be the same, so the default implementation of this service returns a key that just contains the context type. 同じコンテキスト型から異なるモデルを生成するには、サービスを適切な実装に置き換える必要があります。生成されたキーは、 IModelCacheKeyFactory モデルに Equals 影響を与えるすべての変数を考慮して、メソッドを使用して他のモデルキーと比較されます。To produce different models from the same context type, you need to replace the IModelCacheKeyFactory service with the correct implementation; the generated key will be compared to other model keys using the Equals method, taking into account all the variables that affect the model.

次の実装は、 UseIntProperty モデルキャッシュキーを生成するときに、を考慮します。The following implementation takes the UseIntProperty into account when producing a model cache key:

public class DynamicModelCacheKeyFactory : IModelCacheKeyFactory
{
    public object Create(DbContext context)
        => context is DynamicContext dynamicContext
            ? (context.GetType(), dynamicContext.UseIntProperty)
            : (object)context.GetType();
}

最後に、新しいを IModelCacheKeyFactory コンテキストに登録し OnConfiguring ます。Finally, register your new IModelCacheKeyFactory in your context's OnConfiguring:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseInMemoryDatabase("DynamicContext")
        .ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>();

詳細なコンテキストについては、 完全なサンプルプロジェクト を参照してください。See the full sample project for more context.