Ef Core花里胡哨系列(4) 多租户
当然,我们要考虑设计问题,例如,切换
Schema
或者改变数据库时,Ef Core
同样也会刷新改实体的缓存,所以,首次查询将会很慢,不适合大表。
基于Schema
实现多租户
在我的上一篇博客中 [Ef Core花里胡哨系列(3) 动态修改实体对应的表(分表)、多租户]
中我们实现了如何分表,同理,我们可以用近似的方法来切换表的Schema
,只需要一点很小的改动。
csharp
public class SampleDbContext(DbContextOptions<SampleDbContext> options)
: DbContext(options)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable($"User{DateTime.Now.ToString("yyyyMM")}", YourSchema);
base.OnModelCreating(modelBuilder);
}
}
基于多库实现多租户
实现切换数据库我们将会采用的是Interceptor
拦截器来实现。
建议租户相关的操作采用单独的
DbContext
和系统表区分开。
csharp
public class TenantDbConnectionInterceptor<T> : DbConnectionInterceptor
{
public TenantDbConnectionInterceptor()
{
}
public override InterceptionResult ConnectionOpening(DbConnection connection, ConnectionEventData eventData, InterceptionResult result)
{
connection.ConnectionString = "对应租户的连接字符串";
return base.ConnectionOpening(connection, eventData, result);
}
public override ValueTask<InterceptionResult> ConnectionOpeningAsync(DbConnection connection, ConnectionEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default)
{
connection.ConnectionString = "对应租户的连接字符串";
return base.ConnectionOpeningAsync(connection, eventData, result, cancellationToken);
}
}
使用拦截器
csharp
services.AddDbContext<DynamicDbContext>(opts =>
{
opts.AddInterceptors(new TenantDbConnectionInterceptor());
});