Hello Mohamed,
I really have problems to understand some of your questions!
[tenantDatabase].[00000000-0000-0000-0000-00000000001].[table1]
[tenantDatabase].[00000000-0000-0000-0000-00000000001].[table2]
[tenantDatabase].[00000000-0000-0000-0000-00000000001].[table3]
[tenantDatabase].[00000000-0000-0000-0000-00000000002].[table1]
[tenantDatabase].[00000000-0000-0000-0000-00000000002].[table2]
[tenantDatabase].[00000000-0000-0000-0000-00000000002].[table3]
The following code updates the tables for tenant 1 within schema 00000000-0000-0000-0000-000000000001:
Your question about data loss is a different problem and has nothing to do with the multi-tenancy.
Regards,
Tobias
I really have problems to understand some of your questions!
The usecase
Maybe you want to use that stuff differently than I am. My usecase is as follows:- one code first database model (with table1, table2 and table3 for example)
- every tenant has exactly the same tables with the same columns
- multiple tenants (with id 00000000-0000-0000-0000-00000000001 and 00000000-0000-0000-0000-00000000002 for example)
-
one database (with the name tenantDatabase for example)
[tenantDatabase].[00000000-0000-0000-0000-00000000001].[table1]
[tenantDatabase].[00000000-0000-0000-0000-00000000001].[table2]
[tenantDatabase].[00000000-0000-0000-0000-00000000001].[table3]
[tenantDatabase].[00000000-0000-0000-0000-00000000002].[table1]
[tenantDatabase].[00000000-0000-0000-0000-00000000002].[table2]
[tenantDatabase].[00000000-0000-0000-0000-00000000002].[table3]
Reading data of a concrete tenant
The following code instantiates the DbContext for reading data of tenant 1:Guid tenantId = Guid.Parse("00000000-0000-0000-0000-00000000001");
using (var dbContext = TenantDataCtx.TenantDataCtx.Create("databaseServer", "tenantDatabase", "databaseUserName", "databasePassword", tenantId);
{
// everything you do with dbContext will be executed within the schema of tenant 1
// EXAMPLE: Read data from table1
var dataFromTable1OfTenant1 = dbContext.Set<Table1>().ToList();
}
The following code instantiates the DbContext for reading data of tenant 2:Guid tenantId = Guid.Parse("00000000-0000-0000-0000-00000000002");
using (var dbContext = TenantDataCtx.TenantDataCtx.Create("databaseServer", "tenantDatabase", "databaseUserName", "databasePassword", tenantId);
{
// everything you do with dbContext will be executed within the schema of tenant 2
// EXAMPLE: Read data from table2
var dataFromTable2OfTenant2 = dbContext.Set<Table2>().ToList();
}
Update the tables of concrete tenants
The same approach applies for the usage of SqlServerSchemaAwareMigrationSqlGenerator.The following code updates the tables for tenant 1 within schema 00000000-0000-0000-0000-000000000001:
Guid tenantId = Guid.Parse("00000000-0000-0000-0000-000000000001");
string schemaName = tenantId.ToString();
var tenantDataMigrationsConfiguration = new DbMigrationsConfiguration<TenantDataContext.TenantDataCtx>();
tenantDataMigrationsConfiguration.AutomaticMigrationsEnabled = false;
tenantDataMigrationsConfiguration.SetSqlGenerator("System.Data.SqlClient", new SqlServerSchemaAwareMigrationSqlGenerator(schemaName));
tenantDataMigrationsConfiguration.SetHistoryContextFactory("System.Data.SqlClient", (existingConnection, defaultSchema) => new HistoryContext(existingConnection, schemaName));
tenantDataMigrationsConfiguration.TargetDatabase = new System.Data.Entity.Infrastructure.DbConnectionInfo(connectionString, "System.Data.SqlClient");
tenantDataMigrationsConfiguration.MigrationsAssembly = typeof(TenantDataContext.TenantDataCtx).Assembly;
tenantDataMigrationsConfiguration.MigrationsNamespace = "TenantDataContext.Migrations.TenantData"; // Update that namespace to your migration namespace!!!!!!!
DbMigrator tenantDataCtxMigrator = new DbMigrator(tenantDataMigrationsConfiguration);
tenantDataCtxMigrator.Update();
The following code updates the tables for tenant 2 within schema 00000000-0000-0000-0000-000000000002:Guid tenantId = Guid.Parse("00000000-0000-0000-0000-000000000002");
string schemaName = tenantId.ToString();
var tenantDataMigrationsConfiguration = new DbMigrationsConfiguration<TenantDataContext.TenantDataCtx>();
tenantDataMigrationsConfiguration.AutomaticMigrationsEnabled = false;
tenantDataMigrationsConfiguration.SetSqlGenerator("System.Data.SqlClient", new SqlServerSchemaAwareMigrationSqlGenerator(schemaName));
tenantDataMigrationsConfiguration.SetHistoryContextFactory("System.Data.SqlClient", (existingConnection, defaultSchema) => new HistoryContext(existingConnection, schemaName));
tenantDataMigrationsConfiguration.TargetDatabase = new System.Data.Entity.Infrastructure.DbConnectionInfo(connectionString, "System.Data.SqlClient");
tenantDataMigrationsConfiguration.MigrationsAssembly = typeof(TenantDataContext.TenantDataCtx).Assembly;
tenantDataMigrationsConfiguration.MigrationsNamespace = "TenantDataContext.Migrations.TenantData"; // Update that namespace to your migration namespace!!!!!!!
DbMigrator tenantDataCtxMigrator = new DbMigrator(tenantDataMigrationsConfiguration);
tenantDataCtxMigrator.Update();
If you want to have a different tables/columns per tenant than you have to design the database model for every tenant and you have to create migrations separately for every tenant. I think migrations are not well suited for that usecase.Your question about data loss is a different problem and has nothing to do with the multi-tenancy.
Regards,
Tobias