Wechsel zwischen mehrere Modelle mit den gleichen Typ von "DbContext"Alternating between multiple models with the same DbContext type

Das Modell integriert OnModelCreating können eine Eigenschaft für den Kontext ändern, wie das Modell erstellt wurde.The model built in OnModelCreating could use a property on the context to change how the model is built. Es könnte z. B. 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

Wenn Sie versucht, den oben genannten ohne weitere Änderungen Sie jedoch das gleiche Modell nutzen würden jedes Mal ein neuer Kontext, für jeden Wert von erstellt wird 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 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 identisch ist.By default EF assumes that for any given context type the model will be the same. Hierfür die standardmäßige Implementierung des IModelCacheKeyFactory gibt einen Schlüssel, der den Typ des gerade enthält.To accomplish this the default implementation of IModelCacheKeyFactory returns a key that just contains the context type. Dies ändern, Sie ersetzen müssen, die IModelCacheKeyFactory Service.To change this you need to replace the IModelCacheKeyFactory service. Die neue Implementierung muss zurückgegeben wird ein Objekt, das verglichen werden soll, kann andere Modell Schlüssel mithilfe der Equals -Methode, die alle Variablen berücksichtigt, die das Modell auswirken: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();
    }
}