Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在运行时更改DbContext连接_C#_Database_Entity Framework_Reflection_Entity - Fatal编程技术网

C# 在运行时更改DbContext连接

C# 在运行时更改DbContext连接,c#,database,entity-framework,reflection,entity,C#,Database,Entity Framework,Reflection,Entity,我有3个数据库,我想与之合作:A、B和C。 每个表都有相同的表,例如:用户、产品 我想让用户决定运行时使用哪个数据库。 所以我使用EF5并创建了3个edbx文件,这些文件创建了以下类:AdBenties、BDBenties和CDBenties 我怎样才能让他决定所选的数据库,这样我就可以得到它的用户 我是说 var dstuff = from user in selecteddb.users where user.UserEmail == userEmail

我有3个数据库,我想与之合作:A、B和C。 每个表都有相同的表,例如:用户、产品

我想让用户决定运行时使用哪个数据库。 所以我使用EF5并创建了3个edbx文件,这些文件创建了以下类:AdBenties、BDBenties和CDBenties

我怎样才能让他决定所选的数据库,这样我就可以得到它的用户

我是说

var dstuff = from user in selecteddb.users
             where user.UserEmail == userEmail
             select user.UserID;

我曾考虑过使用反射/基类DBEntities,但没有实现这些想法。

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


假设数据库是相同的,您只需要使用一个生成的类。你不需要全部三个,因为它们是相同的。所以让我们选一个,比如说Adbenties

现在,您需要允许她在运行时选择她的连接字符串。如果在app.config/web.config中存储了三个连接字符串,则可以在运行时使用ConfigurationManager加载它们:

呈现选项并以某种方式选择其中一项:

foreach (ConnectionStringSettings connection in connections)
    //display connection.Name

ConnectionStringSettings selected_connection = connections[1];
DBContext的一个构造函数接受连接字符串,因此只需将用户选择的连接字符串传递给AdBenties的构造函数:


这个答案有点晚了,但我认为有一个潜在的方法可以通过一个简洁的扩展方法来实现这一点。正如SLypeteNiceName:-所说,假设所有表/属性都相同,您只需要一个类模型。在这种情况下,我们可以利用EF约定而不是配置加上一些小的框架调用

无论如何,无需进一步ado,注释代码和示例用法如下:

扩展方法类:

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
    );

我现在正是为了你上面提到的目的而使用它,到目前为止,它对我很有用。希望对您有所帮助。

好的,我很清楚,谢谢!,但有一个问题。。。AdBenties没有接受连接字符串的构造函数,尽管它是从DBContext派生的,而DBContext接受连接字符串。我应该向Adbenties添加这样的构造函数吗?或者执行其他操作…?如果我添加以下构造函数:public-adbentiesString-nameOrConnectionString:basename=adbenties{},我会收到以下错误:指定的架构无效。错误:未加载关系“AdbModel.AccessCategoriesGroup”,因为类型“AdbModel.ProductCategory”不可用。我已为您的sceanrio添加了一个替代选项。希望对你有帮助。。。
var defaultString = _myContext.Database.GetDbConnection().ConnectionString;
_myContext.Database.GetDbConnection().ConnectionString ="new connection" or _myContext.Database.GetDbConnection().ChangeDatabase()
//your query..
_myContext.Database.GetDbConnection().ConnectionString = defaultString;
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
    );
var defaultString = _myContext.Database.GetDbConnection().ConnectionString;
_myContext.Database.GetDbConnection().ConnectionString ="new connection" or _myContext.Database.GetDbConnection().ChangeDatabase()
//your query..
_myContext.Database.GetDbConnection().ConnectionString = defaultString;