故事:在我们的 Multi-Tenancy 应用程序(一个PostgreSql数据库,多个架构)中,我们需要对多个架构使用一个DbContext。
我试过的方法:持有一个缓存(字典,其中键是架构名称,值是该架构的上下文)。当为另一个架构实例化新上下文时,我可以看到dbContext架构仍设置为所提供的先前架构。我假设上下文中的模型是按上下文类型在内部缓存的,所以这就是我看到此行为的原因吗?
因此,上面的方法似乎不起作用,我发现实现IModelCacheKeyFactory应该可以解决问题。有谁知道Create方法应该输入什么?任何地方都没有样本或文档。
我发现:
Dynamically changing schema in Entity Framework Core,但它可以回答EF6,因此帮助不多。
最佳答案
这是一个例子。
派生的DbContext,将它的ModelCacheKey(和工厂)替换为“自定义”。
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);
// ...
}
}
使用特定键创建上下文的工厂。
class MyModelCacheKeyFactory : IModelCacheKeyFactory
{
public object Create(DbContext context)
=> new MyModelCacheKey(context);
}
每个上下文的自定义ModelCacheKey。
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;
}
}
关于schema - 如何在EF Core中实现IModelCacheKeyFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41979215/