Чередование между несколькими моделями с одинаковым типом DbContext
Встроенная OnModelCreating
модель может использовать свойство в контексте, чтобы изменить способ построения модели. Например, предположим, что вы хотите настроить сущность по-разному на основе некоторых свойств:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
if (UseIntProperty)
{
modelBuilder.Entity<ConfigurableEntity>().Ignore(e => e.StringProperty);
}
else
{
modelBuilder.Entity<ConfigurableEntity>().Ignore(e => e.IntProperty);
}
}
К сожалению, этот код не будет работать как есть, так как EF создает модель и выполняется OnModelCreating
только один раз, кэширование результата по причинам производительности. Однако вы можете подключиться к механизму кэширования модели, чтобы сделать EF осведомленным о свойстве, производящим различные модели.
EF используется IModelCacheKeyFactory
для создания ключей кэша для моделей. По умолчанию EF предполагает, что для любого заданного типа контекста модель будет одинаковой, поэтому реализация по умолчанию этой службы возвращает ключ, содержащий только тип контекста. Чтобы создать разные модели из одного типа контекста, необходимо заменить IModelCacheKeyFactory
службу правильной реализацией. Созданный ключ будет сравниваться с другими ключами модели с помощью Equals
метода, учитывая все переменные, влияющие на модель.
Следующая реализация учитывается UseIntProperty
при создании ключа кэша модели:
public class DynamicModelCacheKeyFactory : IModelCacheKeyFactory
{
public object Create(DbContext context, bool designTime)
=> context is DynamicContext dynamicContext
? (context.GetType(), dynamicContext.UseIntProperty, designTime)
: (object)context.GetType();
}
Кроме того, необходимо реализовать перегрузку метода Create, который также обрабатывает кэширование модели во время разработки. Как показано в следующем примере:
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);
}
Наконец, зарегистрируйте новое IModelCacheKeyFactory
в контексте OnConfiguring
:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseInMemoryDatabase("DynamicContext")
.ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>();
Дополнительные сведения см. в полном примере проекта .
Отзыв о .NET
.NET — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв: