如何在EF Core中实现IModelCacheKeyFactory [英] How to implement IModelCacheKeyFactory in EF Core

查看:392
本文介绍了如何在EF Core中实现IModelCacheKeyFactory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

故事:在我们的多租户应用程序(一个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.

我发现的东西:
在Entity Framework Core中动态更改架构,但它可以解决EF6问题,因此没有太大帮助。

What I found: Dynamically changing schema in Entity Framework Core but it answers for EF6, so not much help.

推荐答案

这里是一个示例。

派生的DbContext用自定义的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);

        // ...
    }
}

使用特定键创建的工厂。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆