同じ DbContext 型を持つ複数のモデル間で切り替えるAlternating between multiple models with the same DbContext type

組み込まれているモデルOnModelCreatingでした、プロパティを使用して、コンテキストのモデルの構築方法を変更します。The model built in OnModelCreating could use a property on the context to change how the model is built. たとえばを除外する特定のプロパティに使用できます。For example it could be used to exclude a certain property:

public class DynamicContext : DbContext
{
    public bool? IgnoreIntProperty { get; set; }

    public DbSet<ConfigurableEntity> Entities { get; set; }

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

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

IModelCacheKeyFactoryIModelCacheKeyFactory

ただし追加変更なしには、上記を実行しようとした場合は、得られる、同じモデルのすべての値の新しいコンテキストが作成されるたびにIgnoreIntPropertyです。However if you tried doing the above without additional changes you would get the same model every time a new context is created for any value of IgnoreIntProperty. これは、モデルのキャッシュのみを呼び出すことによって、パフォーマンスを向上させるために使用して EF メカニズムにより発生OnModelCreatingとモデルをキャッシュします。This is caused by the model caching mechanism EF uses to improve the performance by only invoking OnModelCreating once and caching the model.

既定では、EF は、任意の指定したコンテキストに対して、モデルの種類が同じであることと仮定します。By default EF assumes that for any given context type the model will be the same. これを実現する既定の実装IModelCacheKeyFactoryのみ、コンテキストの種類を含むキーを返します。To accomplish this the default implementation of IModelCacheKeyFactory returns a key that just contains the context type. 置換する必要があります。 これを変更する、IModelCacheKeyFactoryサービス。To change this you need to replace the IModelCacheKeyFactory service. 新しい実装を使用して他のモデルのキーを比較できるオブジェクトを返す必要があります、Equalsモデルに影響するすべての変数を考慮したメソッド。The new implementation needs to return an object that can be compared to other model keys using the Equals method that takes into account all the variables that affect the model:

public class DynamicModelCacheKeyFactory : IModelCacheKeyFactory
{
    public object Create(DbContext context)
    {
        if (context is DynamicContext dynamicContext)
        {
            return (context.GetType(), dynamicContext.IgnoreIntProperty);
        }
        return context.GetType();
    }
}