I have 3 DBs that I want to work with: A,B and C. each one have the same tables (for example: users, products).
I want to let the user decide (on run-time) which DB he wants to work with. So... I used EF5 and created 3 edbx files which created the following classes: ADBEntities, BDBEntities and CDBEntities.
How can I let him decide the selecteddb so I could get its users?
I mean,
var dstuff = from user in selecteddb.users
where user.UserEmail == userEmail
select user.UserID;
I've thought of using reflection / base class (DBEntities), but didn't get far with those ideas.
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 ADBEntities
var selectedDb = new ADBEntities();
// so only reference the changed properties
// using the object parameters by name
selectedDb.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 == "[email protected]").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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With