Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Migrations - support for dynamic connection string

I can't make the migrations work for a specific scenario.

Our application uses two different models. The first is for the main database and there, the migration is working fine. The second model is for our customers databases which are specific for each customer (of course...) but all share the same model.

So, in the application (ASP.Net MVC 3), we identify the customer using the route and all customers are hosted in the same application. So, for each request we pass a key to our customer model dbContext constructor and with that key we recover the connection string through a simple helper method.

The application is working fine but not the migrations since I found no way to pass the key in the Package Manager Console.

I tried to create my own IDbConnectionFactory but it is not taken into account.

If I try an update-database command with the connection factory I get the following error which is normal since no key is passed but I can see that my connection factory is kicking in (EFCustomerModel.EFConnectionFactory):

PM> update-database  -verbose
Using NuGet project 'EFCustomerModel'.
Using StartUp project 'PMEL.DatabaseSetup'.
System.ArgumentException: Format of the initialization string does not conform to specification starting at index 0.
   at System.Data.Common.DbConnectionOptions.GetKeyValuePair(String connectionString, Int32 currentPosition, StringBuilder buffer, Boolean useOdbcRules, String& keyname, String& keyvalue)
   at System.Data.Common.DbConnectionOptions.ParseInternal(Hashtable parsetable, String connectionString, Boolean buildChain, Hashtable synonyms, Boolean firstKey)
   at System.Data.Common.DbConnectionOptions..ctor(String connectionString, Hashtable synonyms, Boolean useOdbcRules)
   at System.Data.SqlClient.SqlConnectionString..ctor(String connectionString)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(String connectionString, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions)
   at System.Data.SqlClient.SqlConnection.ConnectionString_Set(String value)
   at System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
   at System.Data.SqlClient.SqlConnection..ctor(String connectionString)
   **at EFCustomerModel.EFConnectionFactory.CreateConnection(String nameOrConnectionString) in C:\...\EFCustomerModel\EFConnectionFactory.vb:line 18**
   at System.Data.Entity.Internal.LazyInternalConnection.Initialize()
   at System.Data.Entity.Internal.LazyInternalConnection.get_Connection()
   at System.Data.Entity.Internal.LazyInternalContext.get_Connection()
   at System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config, DbConnectionInfo connectionInfo)
   at System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.GetMigrator()
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore()
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
Format of the initialization string does not conform to specification starting at index 0.

But when I try to pass in my key using the -ConnectionString parameter, then my connection factory is ignored and I get the same error:

PM> update-database  -verbose -ConnectionString:CC99999 -ConnectionProviderName:System.Data.SqlClient
Using NuGet project 'EFCustomerModel'.
Using StartUp project 'PMEL.DatabaseSetup'.
System.ArgumentException: Format of the initialization string does not conform to specification starting at index 0.
   at System.Data.Common.DbConnectionOptions.GetKeyValuePair(String connectionString, Int32 currentPosition, StringBuilder buffer, Boolean useOdbcRules, String& keyname, String& keyvalue)
   at System.Data.Common.DbConnectionOptions.ParseInternal(Hashtable parsetable, String connectionString, Boolean buildChain, Hashtable synonyms, Boolean firstKey)
   at System.Data.Common.DbConnectionOptions..ctor(String connectionString, Hashtable synonyms, Boolean useOdbcRules)
   at System.Data.SqlClient.SqlConnectionString..ctor(String connectionString)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(String connectionString, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions)
   at System.Data.SqlClient.SqlConnection.ConnectionString_Set(String value)
   at System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
   at System.Data.Entity.Internal.LazyInternalConnection.InitializeFromConnectionStringSetting(ConnectionStringSettings appConfigConnection)
   at System.Data.Entity.Internal.LazyInternalConnection.Initialize()
   at System.Data.Entity.Internal.LazyInternalConnection.get_Connection()
   at System.Data.Entity.Internal.LazyInternalContext.get_Connection()
   at System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config, DbConnectionInfo connectionInfo)
   at System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbConnectionInfo connectionInfo)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.GetMigrator()
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore()
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
Format of the initialization string does not conform to specification starting at index 0.

So, is this an unsupported scenario in the migrations or there is another way to pass in my key or maybe there is another way to generate my connection strings?

like image 983
jjslagace Avatar asked Aug 22 '12 18:08

jjslagace


1 Answers

You should be able to pass a key to your custom connection factory with the -ConnectionStringName parameter. This parameter would be passed to the CreateConnection method.

Another possible solution would be to call DB migration from your code:

var configuration = new Configuration();
configuration.TargetDatabase = new DbConnectionInfo(
    "Server=MyServer;Database=MyDatabase;Trusted_Connection=True;", 
    "System.Data.SqlClient");

var migrator = new DbMigrator(configuration);
migrator.Update();
like image 147
Lukas Kabrt Avatar answered Oct 15 '22 14:10

Lukas Kabrt