我使用了“主/从复制”设置的数据库。我有一个主数据库和(至少)一个从数据库,可能是ℕ个从数据库。为简单起见,下文中我将只讨论一个主数据库和一个从数据库,因为确定要使用哪个从数据库包含一些与实际问题无关的业务逻辑。
这是设置的示意图(带有ℕ个从数据库):
在应用程序中(当前使用Dapper),我有以下简化的代码:
abstract class BaseRepo
{
private readonly string _readconn;
private readonly string _writeconn;
public BaseRepo(string readConnection, string writeConnection)
{
_readconn = readConnection; //Actually IEnumerable<string> for ℕ slaves
_writeconn = writeConnection;
}
private SqlConnection GetOpenConnection(string cnstring)
{
var c = new SqlConnection(cnstring);
c.Open();
return c;
}
public SqlConnection GetOpenReadConnection()
{
return this.GetOpenConnection(_readconn);
// Actually we use some business-logic to determine *which* of the slaves to use
}
public SqlConnection GetOpenWriteConnection()
{
return this.GetOpenConnection(_writeconn);
}
}
class CustomerRepo : BaseRepo
{
// ...ctor left out for brevity...
// "Read" functions use the "read" connection
public IEnumerable<Customer> ListCustomers()
{
using (var c = this.GetOpenReadConnection())
{
return c.Query<Customer>("select * from customers order by name");
}
}
// "Write" functions use the "write" connection
public void UpdateCustomer(Customer cust)
{
using (var c = this.GetOpenWriteConnection())
{
c.Execute("update customers set name = @name where id = @id", cust);
}
}
}
我的问题是:假设我想使用Entity Framework(“Code First”,是否相关)而不是Dapper,我应该如何最好地实现相同的概念?在这种情况下,插入/更新/删除会针对“主”数据库执行,而选择操作将针对从服务器(或任何从服务器)执行。EF是否支持此方案?我需要做什么才能使其工作?
附加信息:我已经在SQL Server级别上使用“只读”和“只写”用户作为“最后一道防线”,以避免DAL中出现任何错误。我正在寻找一种限制我的DAL的方法,以避免因“不允许”的操作而捕获SQL Server异常,并首先访问(不正确的)SQL服务器,然后发现所需操作不被允许。我可以像现在一样使用相同的方法;在方法本身中实例化/使用正确的DbContext(例如上面的listcustomers/updatecustomer)。我明白了。但这意味着我必须为每个“CRUD”操作和每个“实体”创建一个“包装器”函数,这就是我一开始从dapper转向EF的原因;只需公开一个DBSet,并让EF处理changetracking / SQL查询等,现在,希望它也能确定每个操作要使用哪个连接字符串。
SaveChanges
来创建上下文,当某些条件为 false 时,它就不会调用base.SaveChanges
。但我不知道你能让它有多安全。也许可以基于数据库名称中的某些命名约定来实现? - Gert Arnold