Zmiana między wieloma modelami o tym samym typie DbContext

Wbudowany model OnModelCreating może używać właściwości w kontekście, aby zmienić sposób tworzenia modelu. Załóżmy na przykład, że chcesz skonfigurować jednostkę w inny sposób na podstawie niektórych właściwości:

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

Niestety ten kod nie będzie działać tak, jak to jest, ponieważ program EF kompiluje model i uruchamia OnModelCreating go tylko raz, buforując wynik ze względów wydajności. Można jednak podłączyć się do mechanizmu buforowania modelu, aby poinformować ef o właściwości tworzącej różne modele.

IModelCacheKeyFactory

Program EF używa elementu IModelCacheKeyFactory do generowania kluczy pamięci podręcznej dla modeli. Domyślnie program EF zakłada, że dla dowolnego typu kontekstu model będzie taki sam, więc domyślna implementacja tej usługi zwraca klucz, który zawiera tylko typ kontekstu. Aby utworzyć różne modele z tego samego typu kontekstu, należy zastąpić IModelCacheKeyFactory usługę poprawną implementacją. Wygenerowany klucz zostanie porównany z innymi kluczami modelu przy użyciu Equals metody, biorąc pod uwagę wszystkie zmienne wpływające na model.

Podczas tworzenia klucza pamięci podręcznej modelu należy uwzględnić następującą UseIntProperty implementację:

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

Należy również zaimplementować przeciążenie metody Create, która obsługuje również buforowanie modelu czasu projektowania. Jak pokazano w poniższym przykładzie:

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

Na koniec zarejestruj nowy IModelCacheKeyFactory w kontekście OnConfiguring:

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

Zobacz pełny przykładowy projekt, aby uzyskać więcej kontekstu.