Střídání mezi více modely se stejným typem DbContext

Model sestavený v OnModelCreating může použít vlastnost z kontextu ke změně způsobu, jakým je model sestaven. Předpokládejme například, že jste chtěli nakonfigurovat entitu odlišně podle některé vlastnosti:

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

Tento kód bohužel nebude fungovat as-is, protože EF sestaví model a spustí OnModelCreating pouze jednou a výsledek uloží do mezipaměti z důvodu výkonu. Můžete se ale zapojit do mechanismu ukládání do mezipaměti, aby EF věděl o vlastnosti, která vytváří různé modely.

IModelCacheKeyFactory

EF používá IModelCacheKeyFactory k vygenerování klíčů mezipaměti pro modely. Ef ve výchozím nastavení předpokládá, že pro libovolný daný typ kontextu bude model stejný, takže výchozí implementace této služby vrátí klíč, který obsahuje pouze typ kontextu. Pokud chcete vytvořit různé modely ze stejného typu kontextu, musíte službu nahradit IModelCacheKeyFactory správnou implementací. Vygenerovaný klíč se porovná s jinými klíči modelu, které používají metodu Equals , a to s ohledem na všechny proměnné, které ovlivňují model.

Při vytváření klíče mezipaměti modelu bere následující implementace v úvahu UseIntProperty:

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

Musíte také implementovat přetížení metody Create, která také zpracovává ukládání modelu návrhu do mezipaměti. Stejně jako v následujícím příkladu:

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

Nakonec zaregistrujte nový IModelCacheKeyFactory v kontextu OnConfiguring:

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

Další kontext najdete v úplném ukázkovém projektu .