Alternando entre vários modelos com o mesmo tipo de DbContextAlternating between multiple models with the same DbContext type

O modelo criado OnModelCreating poderia usar uma propriedade no contexto para alterar como o modelo é criado.The model built in OnModelCreating could use a property on the context to change how the model is built. Por exemplo, ele pode ser usado para excluir determinadas propriedades: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

No entanto se você tentou usar o método acima sem alterações adicionais você obteria o mesmo modelo sempre que um novo contexto é criado para qualquer valor de 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. Isso é causado pelo modelo usa o EF para melhorar o desempenho invocando somente do mecanismo de cache OnModelCreating uma vez e o modelo de armazenamento em cache.This is caused by the model caching mechanism EF uses to improve the performance by only invoking OnModelCreating once and caching the model.

Por padrão o EF pressupõe que para qualquer contexto de determinado tipo de modelo será o mesmo.By default EF assumes that for any given context type the model will be the same. Para fazer isso a implementação padrão de IModelCacheKeyFactory retorna uma chave que contém apenas o tipo de contexto.To accomplish this the default implementation of IModelCacheKeyFactory returns a key that just contains the context type. Para alterar isso, é necessário substituir o IModelCacheKeyFactory service.To change this you need to replace the IModelCacheKeyFactory service. A nova implementação precisa retornar um objeto que pode ser comparado para outras chaves de modelo usando o Equals método que leva em conta todas as variáveis que afetam o modelo: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();
    }
}