Репост из: .NET Разработчик
День 1582. #ЗаметкиНаПолях
Мультитенантные Приложения с EF Core. Окончание
Начало
2. Мультитенантность в раздельных базах данных с помощью EF Core
В некоторых отраслях, таких как здравоохранение, требуется высокая степень изоляции данных, и использование базы данных для каждого клиента является обязательным. Если мы хотим изолировать каждого клиента в отдельной базе данных, нам нужно:
- Применить разные строки подключения для каждого клиента,
- Каким-то образом определять строку подключения для каждого клиента.
Здесь нельзя использовать фильтры запросов, так как мы работаем с разными базами. Поэтому нужно где-то хранить информацию о клиенте и строке подключения. Простым примером (если клиентов относительно немного) может быть сохранение их в настройках приложения:
"Tenants": {
{ "Id": "tenant-1", "ConnectionString":
"Host=tenant1.db;Database=tenant1" },
{ "Id": "tenant-2", "ConnectionString":
"Host=tenant2.db;Database=tenant2" }
}
Затем можно зарегистрировать экземпляр IOptions со списком объектов Tenant. Вот здесь подробнее про паттерн Options.
Также нужно изменить класс TenantProvider, чтобы он возвращал строку подключения для текущего клиента:
public sealed class TenantProvider
{
private IHttpContexAccessor _hca;
private TenantSettings _ts;
public TenantProvider(
IHttpContexAccessor hca,
IOptions opt)
{
_hca = hca;
_ts = opt.Value;
}
public string TenantId => _hca
.HttpContext.Request
.Headers["X-TenantId"];
public string GetConnectionString()
{
return _ts.Tenants
.Single(t => t.Id == TenantId);
}
}
И последняя часть — это регистрация DbContext для динамического разрешения строки подключения для текущего клиента:
builder.Services
.AddDbContext((sp, o) =>
{
var tp = sp.GetRequiredService();
var cs = tp.GetConnectionString();
o.UseSqlServer(cs);
});
При каждом запросе мы создаём новый OrdersContext и подключаемся к соответствующей базе данных для этого клиента. Обязательно следует хранить строки подключения клиента в безопасном месте, таком как Azure Key Vault.
Итого
Это, конечно, базовая реализация, которую можно улучшить, чтобы сделать более надёжной и безопасной. Построение мультитенантных систем — дело непростое, но, если вы понимаете основные принципы, это не должно быть слишком сложно.
Источник: https://www.milanjovanovic.tech/blog/multi-tenant-applications-with-ef-core
Мультитенантные Приложения с EF Core. Окончание
Начало
2. Мультитенантность в раздельных базах данных с помощью EF Core
В некоторых отраслях, таких как здравоохранение, требуется высокая степень изоляции данных, и использование базы данных для каждого клиента является обязательным. Если мы хотим изолировать каждого клиента в отдельной базе данных, нам нужно:
- Применить разные строки подключения для каждого клиента,
- Каким-то образом определять строку подключения для каждого клиента.
Здесь нельзя использовать фильтры запросов, так как мы работаем с разными базами. Поэтому нужно где-то хранить информацию о клиенте и строке подключения. Простым примером (если клиентов относительно немного) может быть сохранение их в настройках приложения:
"Tenants": {
{ "Id": "tenant-1", "ConnectionString":
"Host=tenant1.db;Database=tenant1" },
{ "Id": "tenant-2", "ConnectionString":
"Host=tenant2.db;Database=tenant2" }
}
Затем можно зарегистрировать экземпляр IOptions со списком объектов Tenant. Вот здесь подробнее про паттерн Options.
Также нужно изменить класс TenantProvider, чтобы он возвращал строку подключения для текущего клиента:
public sealed class TenantProvider
{
private IHttpContexAccessor _hca;
private TenantSettings _ts;
public TenantProvider(
IHttpContexAccessor hca,
IOptions opt)
{
_hca = hca;
_ts = opt.Value;
}
public string TenantId => _hca
.HttpContext.Request
.Headers["X-TenantId"];
public string GetConnectionString()
{
return _ts.Tenants
.Single(t => t.Id == TenantId);
}
}
И последняя часть — это регистрация DbContext для динамического разрешения строки подключения для текущего клиента:
builder.Services
.AddDbContext((sp, o) =>
{
var tp = sp.GetRequiredService();
var cs = tp.GetConnectionString();
o.UseSqlServer(cs);
});
При каждом запросе мы создаём новый OrdersContext и подключаемся к соответствующей базе данных для этого клиента. Обязательно следует хранить строки подключения клиента в безопасном месте, таком как Azure Key Vault.
Итого
Это, конечно, базовая реализация, которую можно улучшить, чтобы сделать более надёжной и безопасной. Построение мультитенантных систем — дело непростое, но, если вы понимаете основные принципы, это не должно быть слишком сложно.
Источник: https://www.milanjovanovic.tech/blog/multi-tenant-applications-with-ef-core