启动解析
# 启动解析
# 如何让efcore支持分片
如何让efcore支持分片这边就简单说下
efcore的原生使用需要一个DbContextOptions
也可以是泛型,那么DbContextOptions
是怎么来的,是通过DbContextOptionsBuilder
下的Options
属性来获取的,为了让efcore的dbcontext
可以支持分片功能我们需要将自己的一些配置信息注入到efcore内部,那么只要我们注入到DbContextOptionsBuilder
的Options
这个里面那么efcore内部就可以获取到对应的配置了最简实现
IShardingRuntimeContext shardingRuntimeContext = null;
var dbContextOptionsBuilder = new DbContextOptionsBuilder();
dbContextOptionsBuilder.UseSqlServer("").UseDefaultSharding<DefaultShardingTableDbContext>(shardingRuntimeContext);
var defaultShardingTableDbContext = new DefaultShardingTableDbContext(dbContextOptionsBuilder.Options);
2
3
4
通过上述我们可以看到为了扩展efcore我们只需要做到两步即可
- 第一步创建一个
IShardingRuntimeContext
- 第二部
UseDefaultSharding<DefaultShardingTableDbContext>(shardingRuntimeContext)
# 如何创建IShardingRuntimeContext
接下来问题来到了如何创建IShardingRuntimeContext
IShardingRuntimeContext shardingRuntimeContext = new ShardingRuntimeBuilder<DefaultShardingTableDbContext>()
.UseRouteConfig()
.UseConfig()
.Build();
2
3
4
5
这个ShardingRuntimeBuilder<>
就是最终用来创建IShardingRuntimeContext
的,并且IShardingRuntimeContext
的内部是一个依赖注入的服务所以我一将当前应用程序的声明周期的IServiceProvider传入到内部例如
IShardingRuntimeContext shardingRuntimeContext = new ShardingRuntimeBuilder<DefaultShardingTableDbContext>()
.UseRouteConfig()
.UseConfig()
.Build(applicationServiceProvider);
2
3
4
这样ShardingCore
内部的所有路由都可以获取到当前应用程序的依赖注入配置信息
# 额外配置
如果你的启动使用的如下的配置,并没有将当前应用程序的依赖注入放入,并且DbContext
默认也不是依赖注入获取的那么就需要额外实现一个服务IDbContextCreator
,否则程序将无法正常的进行允许
IShardingRuntimeContext shardingRuntimeContext = new ShardingRuntimeBuilder<DefaultShardingTableDbContext>()
.UseRouteConfig()
.UseConfig()
.Build();
2
3
4
5
如果您是依赖注入获取的DbContext
那么是无需重写IDbContextCreator
的
# 重写IDbContextCreator
首先我们要定义一个自己的DbContextCreator
# 如果你的dbcontext
构造函数有且仅有一个并且是DbContextOptions
的话那么可以这样
public class MyDbContextCreator:ActivatorDbContextCreator<MyDbContext>
{
public override DbContext GetShellDbContext(IShardingProvider shardingProvider)
{
IShardingRuntimeContext shardingRuntimeContext =//通过静态类来实现 ShardingProvider.ShardingRuntimeContext
var dbContextOptionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
dbContextOptionsBuilder.UseDefaultSharding<MyDbContext>(shardingRuntimeContext);
return new MyDbContext(dbContextOptionsBuilder.Options);
}
}
2
3
4
5
6
7
8
9
10
IShardingRuntimeContext
静态类可以这么来实现
public class ShardingProvider
{
private static readonly IShardingRuntimeContext instance;
public static IShardingRuntimeContext ShardingRuntimeContext => instance;
static ShardingProvider()
{
instance=new ShardingRuntimeBuilder<MyDbContext>()
.UseRouteConfig()
.UseConfig()
.ReplaceService<IDbContextCreator, MyDbContextCreator>()
.Build();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
# 如果你的dbcontext
构造函数有多个的情况下那么可以这么来实现
public class MyDbContextCreator: IDbContextCreator
{
/// <summary>
/// 如何创建dbcontext
/// </summary>
/// <param name="shellDbContext"></param>
/// <param name="shardingDbContextOptions"></param>
/// <returns></returns>
public virtual DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions)
{
var outDbContext = (MyDbContext)shellDbContext;
var dbContext = new MyDbContext(shardingDbContextOptions.DbContextOptions,outDbContext.OtherParams);
if (dbContext is IShardingTableDbContext shardingTableDbContext)
{
shardingTableDbContext.RouteTail = shardingDbContextOptions.RouteTail;
}
_ = dbContext.Model;
return dbContext;
}
public virtual DbContext GetShellDbContext(IShardingProvider shardingProvider)
{
IShardingRuntimeContext shardingRuntimeContext =//通过静态类来实现 ShardingProvider.ShardingRuntimeContext
var dbContextOptionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
dbContextOptionsBuilder.UseDefaultSharding<MyDbContext>(shardingRuntimeContext);
return new MyDbContext(dbContextOptionsBuilder.Options);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 总结
如果您是依赖注入使用的ShardingCore
那么基本上只需要配置即可,如果您不是依赖注入的ShardingCore
除了需要配置外还需要一点就是要告诉ShardingCore
如果凭空创建一个ShellDbContext