Change DbContext connection at run-time
a bit late on this answer but I think there's a potential way to do this with a neat little extension method. As slypete (nice name :-)) says, you only need ONE class model, assuming all tables/properties are identical. This being the case, we can take advantage of the EF convention over configuration plus a few little framework calls.
Anyway, without further ado, the commented code and example usage:
the extension method class:
public static class ConnectionTools{ // all params are optional public static void ChangeDatabase( this DbContext source, string initialCatalog = "", string dataSource = "", string userId = "", string password = "", bool integratedSecuity = true, string configConnectionStringName = "") /* this would be used if the * connectionString name varied from * the base EF class name */ { try { // use the const name if it's not null, otherwise // using the convention of connection string = EF contextname // grab the type name and we're done var configNameEf = string.IsNullOrEmpty(configConnectionStringName) ? source.GetType().Name : configConnectionStringName; // add a reference to System.Configuration var entityCnxStringBuilder = new EntityConnectionStringBuilder (System.Configuration.ConfigurationManager .ConnectionStrings[configNameEf].ConnectionString); // init the sqlbuilder with the full EF connectionstring cargo var sqlCnxStringBuilder = new SqlConnectionStringBuilder (entityCnxStringBuilder.ProviderConnectionString); // only populate parameters with values if added if (!string.IsNullOrEmpty(initialCatalog)) sqlCnxStringBuilder.InitialCatalog = initialCatalog; if (!string.IsNullOrEmpty(dataSource)) sqlCnxStringBuilder.DataSource = dataSource; if (!string.IsNullOrEmpty(userId)) sqlCnxStringBuilder.UserID = userId; if (!string.IsNullOrEmpty(password)) sqlCnxStringBuilder.Password = password; // set the integrated security status sqlCnxStringBuilder.IntegratedSecurity = integratedSecuity; // now flip the properties that were changed source.Database.Connection.ConnectionString = sqlCnxStringBuilder.ConnectionString; } catch (Exception ex) { // set log item if required } }}
usage:
// assumes a connectionString name in .config of ADBEntitiesvar selectedDb = new ADBEntities();// so only reference the changed properties// using the object parameters by nameselectedDb.ChangeDatabase ( initialCatalog: "name-of-bdb-initialcatalog", userId: "jackthelad", password: "nosecrets", dataSource: @".\sqlexpress" // could be ip address 100.23.45.67 etc );
I currently use this for exactly the purpose that you mention above and thus far, it's served me very well. Hope it helps in your instance.
Pass the appropriate connection string / connection name when creating a DbContext
http://msdn.microsoft.com/en-us/library/gg679467%28v=vs.113%29.aspx
using (var context = new MyDbContext("Server=localhost;Database=dbA;...")){ return context.Users.Where(u => u.Email == "someemail@google.ca").Single();}
var defaultString = _myContext.Database.GetDbConnection().ConnectionString;_myContext.Database.GetDbConnection().ConnectionString ="new connection" or _myContext.Database.GetDbConnection().ChangeDatabase()//your query.._myContext.Database.GetDbConnection().ConnectionString = defaultString;