Alternando entre vários modelos com o mesmo tipo DbContext

O modelo construído em OnModelCreating pode usar uma propriedade no contexto para modificar a forma como o modelo é construído. Por exemplo, suponha que você queira configurar uma entidade de forma diferente com base em alguma propriedade:

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

Infelizmente, esse código não funcionaria as-is, já que o EF cria o modelo e é executado OnModelCreating apenas uma vez, armazenando o resultado em cache por motivos de desempenho. No entanto, você pode se conectar ao mecanismo de cache de modelo para tornar o EF ciente da propriedade que produz modelos diferentes.

IModelCacheKeyFactory

O EF usa o IModelCacheKeyFactory para gerar chaves de cache para modelos. Por padrão, o EF assume que, para qualquer tipo de contexto, o modelo será o mesmo. Portanto, a implementação padrão desse serviço retorna uma chave que contém apenas o tipo de contexto. Para produzir modelos diferentes do mesmo tipo de contexto, você precisa substituir o IModelCacheKeyFactory serviço pela implementação correta, a chave gerada será comparada com outras chaves de modelo usando o Equals método, levando em consideração todas as variáveis que afetam o modelo.

A implementação a seguir leva em consideração ao UseIntProperty produzir uma chave de cache de modelo:

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

Você também precisa implementar a sobrecarga do método Create que também gerencia o cache de modelo durante a fase de design. Como no exemplo a seguir:

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

    public object Create(DbContext context)
        => Create(context, false);
}

Por fim, registe o seu novo IModelCacheKeyFactory no OnConfiguring do seu contexto.

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

Consulte o projeto de exemplo completo para obter mais contexto.