Wechsel zwischen mehrere Modelle mit den gleichen DbContext-TypAlternating between multiple models with the same DbContext type

Das Modell integriert OnModelCreating eine Eigenschaft für den Kontext verwenden, so ändern, wie das Modell erstellt wird.The model built in OnModelCreating could use a property on the context to change how the model is built. Z. B. könnte verwendet werden, um eine bestimmte Eigenschaft ausschließen: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

Jedoch wenn Sie versucht, die oben genannten ohne weitere Änderungen Sie das gleiche Modell erhalten würden jedes Mal, wenn ein neuer Kontext erstellt wird, für jeden Wert von 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. Dies wird durch das Modell Cachemechanismus EF verwendet wird, um die Leistung zu verbessern, indem Sie nur aufrufen verursacht OnModelCreating einmal und das Zwischenspeichern des Modells.This is caused by the model caching mechanism EF uses to improve the performance by only invoking OnModelCreating once and caching the model.

Standardmäßig wird in EF davon ausgegangen, dass für jeden angegebenen Kontext Typ des Modells gleich bleiben.By default EF assumes that for any given context type the model will be the same. Um dies zu erreichen die standardmäßige Implementierung des IModelCacheKeyFactory gibt einen Schlüssel, die nur den Typ des enthält.To accomplish this the default implementation of IModelCacheKeyFactory returns a key that just contains the context type. Dazu Sie ersetzen müssen die IModelCacheKeyFactory Dienst.To change this you need to replace the IModelCacheKeyFactory service. Die neue Implementierung muss ein Objekt, das verglichen werden kann, andere Modell-Schlüsseln mithilfe von Zurückgeben der Equals -Methode, die alle Variablen berücksichtigt, die das Modell beeinflussen: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();
    }
}