Ef Core花里胡哨系列(3) 动态修改实体对应的表(分表)、多租户
Ef Core花里胡哨系列(3) 动态修改实体对应的表(分表)、多租户
Ef Core
在加载的时候,会执行一次OnModelCreating
用来加载所用到的实体。我们要做的就是刷新Ef Core
上下文中之前缓存的内容。
分表
我们假如有一个程序,会每个月创建一个Table年月
的表,我们要做的是每个月只查询当前月的表,更复杂的逻辑我们以后再来讨论,先了解基本的原理。
如何刷新DbContext
?
Ef Core
通过IModelCacheKeyFactory
来检查当前DbContext
是否发生了变化。如果发生了变化,将会重新执行一次OnModelCreating
。
那么事情就很简单了,我们需要自动或者手动让IModelCacheKeyFactory
产生的Key
发生变化,OnModelCreating
中做好对应的处理就可以了。
实现DbContext
将User
实体映射到User年月
的表上。
如果报错没有
ToTable
方法,添加Microsoft.EntityFrameworkCore.Relational
的引用即可。
public class SampleDbContext(DbContextOptions<SampleDbContext> options)
: DbContext(options)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable($"User{DateTime.Now.ToString("yyyyMM")}");
base.OnModelCreating(modelBuilder);
}
}
实现IModelCacheKeyFactory
我这里做了简化处理,直接检测了当前月份的变化,也可以通过实现一个静态变量由外部动态改变。
public class MyModelCacheKeyFactory : IModelCacheKeyFactory
{
public object Create(DbContext context, bool designTime)
{
return DateTime.Now.ToString("yyyyMM");
}
}
替换DbContext
中的默认实现
services.AddDbContext<SampleDbContext>(opts =>
{
opts.ReplaceService<IModelCacheKeyFactory, MyModelCacheKeyFactory>();
});
多租户
利用这些类似的实现,我们可以实现基于分表的多租户,只需要将实体和租户标识映射到不同的表即可。
后面我会说明如何基于多库、Schema进行多租户管理。