ctions": {
"TestDb": {
"ConnectionString": "xxx",
"DatabaseType": "SqlServer"
},
"TestDb_Read": {
"ConnectionString": "xxx",
"DatabaseType": "SqlServer"
}
}
}
}
class Program
{
static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var services = new ServiceCollection()
.AddSingleton<IConfiguration>(config)
.AddOptions()
.AddSingleton<IConfigureOptions<FxOptions>, FxOptionsSetup>()
.AddScoped<IDbProvider, DbProvider>()
.AddSingleton<IUnitOfWorkFactory, UnitOfWorkFactory>()
.AddSingleton<IRepositoryFactory, RepositoryFactory>()
.AddSingleton<IDbContextOptionsBuilderUser, SqlServerDbContextOptionsBuilderUser>()
.AddSingleton<DbContextOptionsBuilderOptions>(new DbContextOptionsBuilderOptions(new DbContextOptionsBuilder<TestDbContext>(), null, typeof(TestDbContext)));
var serviceProvider = services.BuildServiceProvider();
var dbProvider = serviceProvider.GetRequiredService<IDbProvider>();
var uow = dbProvider.GetUnitOfWork<TestDbContext>("TestDb"); // 访问主库
var repoDbTest = uow.GetRepository<DbTest, int>();
var obj = new DbTest { Name = "123", Date = DateTime.Now.Date };
repoDbTest.Insert(obj);
uow.SaveChanges();
Console.ReadKey();
var uow2 = dbProvider.GetUnitOfWork<TestDbContext>("TestDb_Read");
var uow2 = dbProvider.GetUnitOfWork<TestDbContext>("TestDb_Read"); // 访问从库
var repoDbTest2 = uow2.GetReadOnlyRepository<DbTest, int>();
var data2 = repoDbTest2.GetFirstOrDefault();
Console.WriteLine($"id: {data2.Id} name: {data2.Name}");
Console.ReadKey();
}
}
这里直接用控制台来做一个例子,中间多了一个Console.ReadKey()是因为我本地没有配置主从模式,所以实际上我是先插入数据,然后复制到另一个数据库里,再进行读取的.
总结
本文给出的解决方案适用于系统中存在多个不同的上下文,能够适应复杂的业务场景.但对已有代码的侵入性比较大,不知道有没有更好的方案,欢迎一起探讨.