c# - .Net Core 动态 dbContext
问题描述
我有两个 DbContext 共享同一个存储库。以下是我现有的代码:
启动.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);
数据库上下文.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
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
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;
}
}
有什么解决方案可以让我的存储库调用动态 DbContext 而不是使用 switch case?这是因为如果我对存储库中的每个函数都使用 switch case,它将变得多余且难以维护。
解决方案
此解决方案适用于多租户类型的场景,在这些场景中,您具有相同的架构并且需要在基于租户的不同数据库上运行相同的查询。
您可以拥有一个 DbContext,但动态传递 ConnectionString 以连接到不同的数据库。
由于您只有一个 DbContext,因此您的所有存储库都将依赖于该 DbContext。尽管您需要根据租户将正确的连接字符串传递给 DbContext。
您可以创建并实现ITenantDbContextFactory
which 将查看请求以确定要使用的 ConnectionString 并基于该请求创建 DbContext
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;
}
}
推荐阅读
- python - 如何将 .txt 文件保存到 python 列表中的多个路径
- python - 如何使用 csv 中的数据替换 txt 文件模板中的占位符?
- installation - 如果安装了程序,Inno Setup 会跳转到第二页
- c++ - 在 C 中使用 _EXFUN ()
- php - 无法通过php更新mysql中的行
- javascript - S3 放入签名 URL 400 错误
- python - 使用正则表达式获取、编辑和替换字符串
- ios - React-Native:在教程中尝试与本机模块取得联系时出错
- python - 如何使用 socket.send() 发送任意对象?
- variables - 来自命令行的 Makefile 和变量目标