У меня есть настройка базы данных с использованием репликации master/slave. У меня есть один мастер и (по крайней мере) один раб, возможно, рабы. Для простоты здесь я расскажу об одном ведущем, одном подчиненном, потому что определение того, какой подчиненный использовать, включает некоторую бизнес-логику, не относящуюся к реальной проблеме.
Здесь схема установки (с помощью ведомых устройств):
В приложении (в настоящее время используется 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")
.AsEnumerable();
}
}
// "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 ( "сначала код", если это необходимо) вместо Dapper; как мне лучше всего идти по той же концепции; вставки/обновления/удаления выполняются в базе данных "master", а выборки выполняются с ведомым (или любым из ведомых устройств). Поддерживает ли EF этот сценарий вообще? Что мне нужно сделать, чтобы сделать эту работу?
Дополнительная информация. Я уже использую "только для чтения" и "только для записи" на уровне SQL Server как "последнюю строку защиты", чтобы предотвратить ошибки в DAL. То, что я ищу, - это метод ограничения моего DAL, чтобы избежать необходимости исключать исключения SQL Server из-за "недопустимых" действий и необходимости сначала обращаться к (некорректному) SQL-серверу, прежде чем обнаруживать требуемое действие. не допускается. Я мог бы использовать тот же подход, что и сейчас; создать экземпляр/использовать правильный DbContext в самом методе (listcustomers/updatecustomer в приведенном выше примере). Я понимаю. Но это означало бы, что я должен был бы создать функцию "обертки" для каждого действия "CRUD" для каждого "сущности", что было бы причиной того, почему я перешел от dapper к EF в первую очередь; просто выставляйте DBSet и EF позаботитесь о чанстрекинг/SQL-запросах и т.д., и теперь, надеюсь, также выясните, какую строку подключения использовать для каждого действия.