我想要使用3个DB:A,B和C. 每个人都有相同的表格(例如:用户,产品)。
我想让用户决定(在运行时)他想要使用哪个数据库。 所以...我使用了EF5并创建了3个edbx文件,这些文件创建了以下类:ADBEntities,BDBEntities和CDBEntities。
我如何让他决定所选的db以便我可以获得其用户?
我的意思是,
var dstuff = from user in selecteddb.users
where user.UserEmail == userEmail
select user.UserID;
我曾想过使用反射/基类(DBEntities),但对这些想法并没有太大的帮助。
答案 0 :(得分:12)
这个答案有点晚了,但我认为用一个简洁的小扩展方法有可能做到这一点。正如slypete(好名字:-))所说,你只需要一个类模型,假设所有表/属性都相同。在这种情况下,我们可以利用EF约定优于配置以及一些小框架调用。
无论如何,不用多说,注释代码和示例用法:
扩展方法类:
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
}
}
}
用法:
// 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
);
我目前正在将此用于上面提到的目的,到目前为止,它非常适合我。希望它对您的实例有所帮助。
答案 1 :(得分:4)
在创建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();
}
答案 2 :(得分:0)
假设数据库完全相同,您只需使用其中一个生成的类。你不需要全部三个(因为它们是相同的)。所以我们选择一个 - 让我们说ADBEntities
。
现在,您需要允许她在运行时选择她的连接(连接字符串)。如果您的app.config / web.config中存储了三个连接字符串,则可以使用ConfigurationManager
在运行时加载它们:
var connections = ConfigurationManager.ConnectionStrings;
展示选择并以某种方式选择其中一个:
foreach (ConnectionStringSettings connection in connections)
//display connection.Name
ConnectionStringSettings selected_connection = connections[1];
其中一个DBContext
的构造函数接受一个连接字符串,所以只需将用户选择的连接字符串传递给ADBEntities
的构造函数:
using (var selecteddb = new ADBEntities(selected_connection.ConnectionString))
{
var dstuff = from user in selecteddb.users
where user.UserEmail == userEmail
select user.UserID;
}
答案 3 :(得分:0)
var defaultString = _myContext.Database.GetDbConnection().ConnectionString;
_myContext.Database.GetDbConnection().ConnectionString ="new connection" or _myContext.Database.GetDbConnection().ChangeDatabase()
//your query..
_myContext.Database.GetDbConnection().ConnectionString = defaultString;