Comments (4)
@rowanfreeman-acutro the main point to keep in mind, is that NpgsqlDataSources should be long lived - created once and used throughout the application. Your original code above creates an NpgsqlDataSource for each and every DbContext, which is bad.
We definitely need to do some work to improve multi-tenant scenario (especially with NpgsqlDataSource) - I hope to get to do work on this for 9.0. But in the meantime, take a look at this link, which discusses DbContext pooling and multi-tenancy.
In a nutshell, you generally need to have a singleton registry of NpgsqlDataSources - one per tenant; this registry is a singleton since as I wrote above, a data source instance should live throughout your application. Then, you need to have a way for your DbContext to get initialized with the correct NpgsqlDataSource instance - the link above shows how to do that for a DbContextFactory.
Note that currently, having different NpgsqlDataSource instances (one-per-tenant) causes some trouble inside EF itself - that's exactly what #3086 will fix for 9.0.
from efcore.pg.
Thanks @roji, great stuff. Yeah that's the path I originally went down. I had a singleton class that had a dictionary of a few NpgsqlDataSources - one for each tenant, so that they would be reused. I also tried using a static class for the same thing.
But no matter what I tried, including consulting the link you mentioned, I just couldn't get anything to work.
Eventually EF creates too many internal IServiceProviders and throws an exception/warning.
Thanks though, it sounds like 3086 will contribute to this becoming more viable.
from efcore.pg.
I've come up with a solution to this problem using an EF interceptor. But after spending so many hours researching this, I'm really skeptical about my solution because I haven't seen it proposed anywhere else.
But it works; I successfully connected to four different databases, depending on the IServiceScope
, using EF and Npgsql. No warnings, no errors.
public sealed class TenantDbConnectionInterceptor(ITenantContextAccessor tenantContextAccessor)
: DbConnectionInterceptor
{
public override ValueTask<InterceptionResult> ConnectionOpeningAsync(
DbConnection connection,
ConnectionEventData eventData,
InterceptionResult result,
CancellationToken cancellationToken = new()
) => ValueTask.FromResult(ConnectionOpening(connection, eventData, result));
public override InterceptionResult ConnectionOpening(
DbConnection connection,
ConnectionEventData eventData,
InterceptionResult result
)
{
var tenant = tenantContextAccessor.Tenant;
var connectionString = tenant?.ConnectionString ?? string.Empty;
connection.ConnectionString = connectionString;
return result;
}
}
Can anyone see a problem with this?
from efcore.pg.
I had a singleton class that had a dictionary of a few NpgsqlDataSources - one for each tenant, so that they would be reused.
Yep, that's a very good approach.
Eventually EF creates too many internal IServiceProviders and throws an exception/warning.
That warning just means that you're instantiating more than some fix number of service providers, to help users catch the scenario where they're creating a service provider for each and every DbContext (which would be very bad). If you have a fixed number of tenants, and each tenant has a single NpgsqlDataSource (which, before #3086, causes a single EF service provider to be created), then you can safely suppress the warning and just proceed.
from efcore.pg.
Related Issues (20)
- Error retrieving data when combining TPH and complex types
- Unable to Fetch Data from Stored Procedure with Cursor as return type and getting required column id was not present in the results of a "FromSql" operation.
- Implement migration locking
- Replace type reloading mechanism with the new EF migration extensibility mechanism
- DateOnly - en_GB date flipped from October to April. HOT 2
- LTree column type doens worked with migration
- Errors on mapping enum types to SQL and storing into database
- Is there way to translate EF Core query to WITH Queries (Common Table Expressions) ? HOT 3
- Select or filter Length of string contained in JsonB column
- Value Conversion Not Applied when using DbFunction in EF Core HOT 1
- ExecuteDelete cloud not betranslated but querying can HOT 3
- Warning: Found conflicts between different versions of "Microsoft.EntityFrameworkCore.Relational" that could not be resolved on Microsoft.EntityFrameworkCore.Relational 8.0.4 and 8.0.7 HOT 4
- Received backend message ParseComplete while expecting BindCompleteMessage using pgcat pooler
- Guidance for NodaTime postgres data types HOT 3
- v8.0.4 - First async query to run fails HOT 1
- SRID is ignored when writing NetTopologySuite Geometry properties inside objects mapped with ToJson()
- Is Npgsql.EntityFrameworkCore.PostgreSQL stop updating? HOT 2
- Null value in column of relation table violates not-null constraint HOT 11
- Issue Configuring `EnableDynamicJson()` on Data Source with a Multi-Tenant API Leveraging Postgres Row-Level Security
- EF not persisting updating value converted collections to JSON HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from efcore.pg.