如何在EF Core中实现IModelCacheKeyFactory

时间:2017-02-01 11:56:56

标签: schema entity-framework-core

故事:在我们的多租户应用程序(一个PostgreSql数据库,多个模式)中,我们需要对多个模式使用一个DbContext。

我尝试过:持有缓存(Dictionary,其中key是模式名称,value是该模式的上下文)。在为另一个模式设置新上下文时,我可以看到dbContext模式仍然设置为提供的先前模式。我假设上下文中的模型是由上下文类型在内部缓存的,所以这就是我看到这种行为的原因吗?

所以上面似乎没有用,我发现实现IModelCacheKeyFactory应该可以解决问题。有谁知道应该进入Create方法的内容呢?任何地方都没有样品或文件。

我找到了什么: Dynamically changing schema in Entity Framework Core但它为EF6提供了答案,所以帮助不大。

2 个答案:

答案 0 :(得分:11)

以下是一个例子:

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);
}

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;
    }
}

答案 1 :(得分:0)

文档https://github.com/aspnet/EntityFramework.Docs/tree/master/samples/core/DynamicModel中实际上有一个演示项目,为方便起见添加了帖子!