I found many similar questions and posts how to do it, but I'm not sure which approach is better. I think that I need some DbContextFactory class which will return me context depending on the TenantId, but I don't know how to achieve this with OnModelCreating. I mostly saw posts about db-per-tenant architecture, and I'm not sure that I know how to bound schema to context(via user?). I tried to follow this https://romiller.com/2011/05/23/ef-4-1-multi-tenant-with-code-first/ but looks like this is not suitable for latest EF version. I also checked this Multi-Tenant With Code First EF6 but IDbModelCacheKeyProvider changed and now requires DbContext in Create, opposite to what I want to do. Can you please give me example of how this is done?
Asked
Active
Viewed 1,912 times
5
-
If you need different schema per tenant, why not database per tenant then. Then you can register different context in DI based on incoming request. – Fabio Jan 14 '19 at 07:58
-
schema per tenant needs less server resources – Jamil Jan 14 '19 at 07:59
-
Then use different contexts per tenant. – Fabio Jan 14 '19 at 08:02
-
Yes, I'm trying to figure out how to use different contexts per tenant – Jamil Jan 14 '19 at 08:04
-
1You can have common context with Global query filters for tables shared between tenants and separate context for tenant's own tables. But I would suggest to use same schema for all tenants and rely on Global query filters. With same schema your application code don't need to worry about schema, it will "work" for any tenant. – Fabio Jan 14 '19 at 08:10
-
True, but we decided to use different schemas for better isolation, and I think that this approach will work faster when tables get larger. Not sure about last statement though. I don't understand how to create context during runtime for given tenant schema. – Jamil Jan 14 '19 at 08:19
1 Answers
4
Use this code to set a default schema in your context:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("blogging");
}
Create another context using the same connection string and then do:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("mydifferentschemaname");
}
This shoud achieve what you desire.
There is more info here.
You can also map tables (entities) to schemas like:
modelBuilder.Entity<Department>().ToTable("t_Department", "school");

Jammer
- 9,969
- 11
- 68
- 115
-
I will have same tables for each schema. Where should I pass schema name? – Jamil Jan 14 '19 at 08:48
-
1
-
1I ended up creating a class with SchemaName property which is inherited from DbContext, and receives SchemaName in the constructor, which is then used in OnModelCreating. – Jamil Jan 14 '19 at 10:54