Freigeben über


Wechselt zwischen mehreren Modellen mit demselben DbContext-Typ

Das integrierte OnModelCreating Modell kann eine Eigenschaft im Kontext verwenden, um zu ändern, wie das Modell erstellt wird. Angenommen, Sie wollten eine Entität je nach Eigenschaft anders konfigurieren:

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

Leider funktioniert dieser Code nicht as-is, da EF das Modell erstellt und OnModelCreating nur einmal ausführt, wobei das Ergebnis aus Leistungsgründen zwischengespeichert wird. Sie können sich jedoch in den Modell-Cache-Mechanismus einklinken, um EF über die Eigenschaft zu informieren, die unterschiedliche Modelle erzeugt.

IModelCacheKeyFactory

EF verwendet das IModelCacheKeyFactory, um Cache-Schlüssel für Modelle zu erzeugen; standardmäßig geht EF davon aus, dass das Modell für einen gegebenen Kontexttyp identisch ist. Daher gibt die Standardimplementierung dieses Dienstes einen Schlüssel zurück, der nur den Kontexttyp enthält. Um verschiedene Modelle aus demselben Kontexttyp zu erstellen, müssen Sie den IModelCacheKeyFactory Dienst durch die richtige Implementierung ersetzen. Der generierte Schlüssel wird mit anderen Modellschlüsseln mit der Equals Methode verglichen, wobei alle Variablen berücksichtigt werden, die sich auf das Modell auswirken.

Die folgende Implementierung berücksichtigt beim Erstellen eines Modellcacheschlüssels Folgendes UseIntProperty :

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

Außerdem müssen Sie die Überladung der Create-Methode implementieren, die auch das Zwischenspeichern von Entwurfszeitmodellen behandelt. Wie im folgenden Beispiel gezeigt:

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);
}

Registrieren Sie schließlich Ihr neues IModelCacheKeyFactory im Kontext Ihres OnConfiguring.

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

Weitere Kontexte finden Sie im vollständigen Beispielprojekt .