如何在 EF Core 中实现 IModelCacheKeyFactory [英] How to implement IModelCacheKeyFactory in EF Core
问题描述
故事:在我们的多租户应用程序(一个 PostgreSql 数据库,多个架构)中,我们需要针对多个架构使用一个 DbContext.
The story: in our multi-tenant app (one PostgreSql db, multiple schemas) we need to use one DbContext against multiple schemas.
我尝试过的:持有缓存(字典,其中键是模式名称,值是该模式的上下文).当为另一个模式建立新的上下文时,我可以看到 dbContext 模式仍然设置为以前提供的模式.我假设上下文中的模型是按上下文类型在内部缓存的,所以这就是我看到这种行为的原因?
What I tried: holding a cache (Dictionary, where key is schema name, value is the context for that schema). When instatiating new context for another schema I can see that dbContext schema is still set to previous schema provided. I assume the model in context is cached internally by context type, so that is the reason I see this behavior?
以上似乎不起作用,我发现实现 IModelCacheKeyFactory 应该可以解决问题.有谁知道创建 方法呢?任何地方都没有示例或文档.
So above doesn't seem to work and I found that implementing IModelCacheKeyFactory should do the trick. Does anyone know what should go into Create method though? There are no samples nor documentation anywhere.
我发现了什么:在实体框架核心中动态改变架构,但它回答 EF6,所以帮助不大.
What I found: Dynamically changing schema in Entity Framework Core but it answers for EF6, so not much help.
推荐答案
这是一个例子.
派生的 DbContext,用自定义的替换它的 ModelCacheKey(和工厂).
Derived DbContext that replaces it's ModelCacheKey (and factory) with a Custom one.
class MyDbContext : DbContext
{
public MyDbContext(string schema)
{
Schema = schema;
}
public string Schema { get; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options
.UseSqlServer("...")
.ReplaceService<IModelCacheKeyFactory, MyModelCacheKeyFactory>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema(Schema);
// ...
}
}
使用特定键创建上下文的工厂.
The factory that creates the Context with a specific key.
class MyModelCacheKeyFactory : IModelCacheKeyFactory
{
public object Create(DbContext context)
=> new MyModelCacheKey(context);
}
每个上下文的自定义 ModelCacheKey.
The custom ModelCacheKey per context.
class MyModelCacheKey : ModelCacheKey
{
string _schema;
public MyModelCacheKey(DbContext context)
: base(context)
{
_schema = (context as MyDbContext)?.Schema;
}
protected override bool Equals(ModelCacheKey other)
=> base.Equals(other)
&& (other as MyModelCacheKey)?._schema == _schema;
public override int GetHashCode()
{
var hashCode = base.GetHashCode() * 397;
if (_schema != null)
{
hashCode ^= _schema.GetHashCode();
}
return hashCode;
}
}
这篇关于如何在 EF Core 中实现 IModelCacheKeyFactory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!