在具有相同 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 知道生成不同模型的属性。
IModelCacheKeyFactory
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);
}
最后,在上下文的 OnConfiguring
中注册新的 IModelCacheKeyFactory
:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseInMemoryDatabase("DynamicContext")
.ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>();
请参阅完整示例项目以了解更多上下文。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈