Zmiana między wieloma modelami o tym samym typie DbContext

Model zbudowany w OnModelCreating może używać właściwości kontekstu, aby zmienić sposób, w jaki jest konstruowany. 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 zadziałałby as-is, 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 odpowiedzialnej za generowanie różnych modeli.

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.

Następująca implementacja uwzględnia UseIntProperty podczas tworzenia klucza pamięci podręcznej modelu.

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óre obsługuje buforowanie modelu na etapie 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.