在运行时更改DbContext连接

use*_*270 4 c# database reflection entity entity-framework

我有3个我想要使用的DB:A,B和C.每个都有相同的表(例如:用户,产品).

我想让用户决定(在运行时)他想要使用哪个DB.所以...我使用了EF5并创建了3个edbx文件,这些文件创建了以下类:ADBEntities,BDBEntities和CDBEntities.

我如何让他决定所选的db以便我可以获得其用户?

我的意思是,

var dstuff = from user in selecteddb.users
             where user.UserEmail == userEmail
             select user.UserID;
Run Code Online (Sandbox Code Playgroud)

我曾想过使用反射/基类(DBEntities),但没有对这些想法有所了解.

jim*_*lan 13

这个答案有点晚了,但我认为用一个简洁的小扩展方法有可能做到这一点.正如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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

// 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
    );
Run Code Online (Sandbox Code Playgroud)

我目前正在将此用于上面提到的目的,到目前为止,它对我很有帮助.希望它对您的实例有所帮助.


Mat*_*hew 6

创建连接时传递适当的连接字符串/连接名称 DbContext

http://msdn.microsoft.com/zh-cn/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();
} 
Run Code Online (Sandbox Code Playgroud)