简体   繁体   English

.Net Core 动态 dbContext

[英].Net Core Dynamic dbContext

I has two DbContext sharing the same repository.我有两个 DbContext 共享同一个存储库。 The following is my existing codes:以下是我现有的代码:

Startup.cs启动文件

        services.AddDbContext<SgAesMasterContext>(options =>  options.UseSqlServer(Configuration.GetConnectionString("SgAesMasterContext"),
            b => b.UseRowNumberForPaging()), ServiceLifetime.Scoped);

        services.AddDbContext<MyAesMasterContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyAesMasterContext"),
            b => b.UseRowNumberForPaging()), ServiceLifetime.Scoped);

DbContext.cs数据库上下文

public class SgAesMasterContext : DbContext
{
    public DbSet<Company> Companies { get; set; }

    public SgAesMasterContext(DbContextOptions<SgAesMasterContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    }
}

public class MyAesMasterContext : DbContext
{
    public DbSet<Company> Companies { get; set; }

    public MyAesMasterContext(DbContextOptions<MyAesMasterContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    }
}

UnitOfWork.cs工作单元.cs

public class AesMasterUnitOfWork: IAesMasterUnitOfWork
{
    private readonly SgAesMasterContext sgAesMasterContext;
    private readonly MyAesMasterContext myAesMasterContext;

    public AesMasterUnitOfWork(SgAesMasterContext sgAesMasterContext, MyAesMasterContext myAesMasterContext)
    {
        this.sgAesMasterContext = sgAesMasterContext;
        this.myAesMasterContext = myAesMasterContext;
    }

    public SgAesMasterContext SgAesMasterContext { get { return sgAesMasterContext; } }
    public MyAesMasterContext MyAesMasterContext { get { return myAesMasterContext; } }
    public CompanyRepository CompanyRepo { get { return new CompanyRepository(sgAesMasterContext, myAesMasterContext); } }

    public void Dispose()
    {
        sgAesMasterContext.Dispose();
        myAesMasterContext.Dispose();
    }
}

CompanyRepository.cs CompanyRepository.cs

public class CompanyRepository
{
    protected readonly SgAesMasterContext sgAesMasterContext;
    protected readonly MyAesMasterContext myAesMasterContext;

    public CompanyRepository(SgAesMasterContext sgAesMasterContext, MyAesMasterContext myAesMasterContext)
    {
        this.sgAesMasterContext = sgAesMasterContext;
        this.myAesMasterContext = myAesMasterContext;
    }

    public async Task<List<Company>> GetCompanies(string country)
    {
        List<Company> companies = new List<Company>();

        switch (country)
        {
            case "SG":
                companies = await sgAesMasterContext.Companies.Where(x => x.Company_Status == "A" && x.Status == "0").ToListAsync();
                break;
            case "MY":
                companies = await myAesMasterContext.Companies.Where(x => x.Company_Status == "A" && x.Status == "0").ToListAsync();
                break;
        }

        return companies;
    }
}

Is there any solution that I can make my repository to call a dynamic DbContext instead of using switch case?有什么解决方案可以让我的存储库调用动态 DbContext 而不是使用 switch case? This is because if I using switch case for every function in my repository, it will become redundant and difficult to maintain.这是因为如果我对存储库中的每个函数都使用 switch case,它将变得多余且难以维护。

This solution is good for multi-tenant types of scenarios, where you have same schema and need to run same query but on different databases based on the tenant.此解决方案适用于多租户类型的场景,其中您具有相同的架构,需要运行相同的查询,但基于租户在不同的数据库上。

You can have a single DbContext but pass ConnectionString dynamically to connect to different databases.您可以拥有单个 DbContext 但动态传递 ConnectionString 以连接到不同的数据库。

Since you have only one DbContext all your repository will depend on that DbContext.由于您只有一个 DbContext,因此您的所有存储库都将依赖于该 DbContext。 Though you need to pass the correct connection string to DbContext based on tenant.尽管您需要根据租户将正确的连接字符串传递给 DbContext。

you can create and implement ITenantDbContextFactory which will look into request to identify which ConnectionString to use and create DbContext based on that您可以创建和实施ITenantDbContextFactory ,它将调查请求以识别要使用的 ConnectionString 并基于该请求创建 DbContext

setup ITenantDbContextFactory in depedency injection在依赖注入中设置ITenantDbContextFactory

public class TenantDbContextFactory : ITenantDbContextFactory 
{
       public TenantDbContext GetDbContext()
       {
             string country;
               // Read Request to identify correct tenant
             switch (country)
             {
                 case "SG":
                      return new TenantDbContext("connectionstring for Sg")
                break;
                 case "MY":
                      return new TenantDbContext("connectionstring for my")
                break;
             }
       }
}
public class TenantDbContext: DbContext
{
    public DbSet<Company> Companies { get; set; }

    public TenantDbContext(DbContextOptions<TenantDbContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    }
}
public class TenantUnitOfWork: ITenantUnitOfWork
{
    private readonly TenantDbContext tenantDbContext;

    public TenantUnitOfWork(ITenantDbContextFactory tenantDbContextFactory)
    {
        this.tenantDbContext= tenantDbContextFactory.GetDbContext();
    }

    public TenantDbContext  TenantDbContext  { get { return tenantDbContext; } }
    public CompanyRepository CompanyRepo { get { return new CompanyRepository(tenantDbContext); } }

    public void Dispose()
    {
        tenantDbContext.Dispose();
    }
}
public class CompanyRepository
{
    protected readonly TenantDbContext tenantDbContext ;

    public CompanyRepository(TenantDbContext tenantDbContext)
    {
        this.tenantDbContext = tenantDbContext ;
    }

    public async Task<List<Company>> GetCompanies()
    {
        List<Company> companies = new List<Company>();

        companies = await tenantDbContext.Companies.Where(x => x.Company_Status == "A" && x.Status == "0").ToListAsync();

        return companies;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM