在具有相同 DbContext 类型的多个模型之间交替Alternating between multiple models with the same DbContext type

内置的模型 OnModelCreating 可以使用上下文中的属性来更改模型的生成方式。 例如,假设你想要根据某些属性以不同的方式配置实体:

  1. protected override void OnModelCreating(ModelBuilder modelBuilder)
  2. {
  3. if (UseIntProperty)
  4. {
  5. modelBuilder.Entity<ConfigurableEntity>().Ignore(e => e.StringProperty);
  6. }
  7. else
  8. {
  9. modelBuilder.Entity<ConfigurableEntity>().Ignore(e => e.IntProperty);
  10. }
  11. }

遗憾的是,此代码不会按原样工作,因为 EF 只构建模型并运行 OnModelCreating 一次,因此性能原因会缓存结果。 但是,可以挂钩到模型缓存机制,使 EF 知道生成不同模型的属性。

IModelCacheKeyFactoryIModelCacheKeyFactory

EF 使用 IModelCacheKeyFactory 来生成模型的缓存键; 默认情况下,ef 假设对于任何给定的上下文类型,模型都是相同的,因此该服务的默认实现将返回只包含上下文类型的键。 若要从相同的上下文类型生成不同的模型,您需要将该服务替换为 IModelCacheKeyFactory 正确的实现; 使用方法将生成的键与其他模型键进行比较,并考虑 Equals 影响模型的所有变量。

以下实现在 UseIntProperty 生成模型缓存键时采用了 into 帐户:

  1. public class DynamicModelCacheKeyFactory : IModelCacheKeyFactory
  2. {
  3. public object Create(DbContext context)
  4. => context is DynamicContext dynamicContext
  5. ? (context.GetType(), dynamicContext.UseIntProperty)
  6. : (object)context.GetType();
  7. }

最后, IModelCacheKeyFactory 在上下文中注册新的 OnConfiguring

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

有关更多上下文,请参阅完整的示例项目