I have an ASP.NET Core 3.1 application that uses an existing Postgres database where each tenant is stored in a separate schema. This works well in HTTP requests, the tenant identifier is stored on the request and in my DbContext I have the following code in the OnConfiguring method:
if (this._httpContextAccessor.HttpContext?.Items["tenant"] != null)
{
string tenant = this._httpContextAccessor.HttpContext.Items["tenant"].ToString();
builder.SearchPath = tenant;
}
else
{
throw new InvalidOperationException("The defined tenant does not exist. Cannot create DB Context");
}
This adjusts the Postgres search path to the tenant for the current request.
I'm now trying to add a background service that also needs to use the database. My background service uses an IServiceProvider and I tried to create my DbContext as following, which obviously doesn't work due to the multitenant implementation I used:
using var scope = this.serviceProvider.CreateScope();
var context = scope.ServiceProvider.GetService<MyDbContext>();
The background service doesn't have a tenant like an HTTP request has, it needs to handle that aspect itself and generate DbContexts with different tenants.
I'm not sure how to adapt my context in a way so that I can create instances with different tenants. Or whether that is actually what I should be doing at all, or if there are better ways to handle this. I know the multitenancy via Postgres schema isn't a typical case for ASP.NET Core, but that's nothing I can change right now.
How can and should I use DbContext with tenants based on Postgres schemas when I need to use it from both HTTP requests and in Background services that are not associated with a specific tenant (but e.g. cycle through tenants to perform a job on each tenant)?