如何使用 C# 在 运行 时间覆盖在 Web.config 文件中设置的数据库?
How to override the database that is set in the Web.config file at run time using C#?
我有一个上下文 class,它将在构造函数中接受一个连接名称。然后它允许我连接到特定的服务器。
我想知道如何在 运行 时更改该连接的默认数据库。
这是我所做的
在 Web.config 文件中,我添加了以下连接字符串
<connectionStrings>
<add name="BaseConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ScripterDynamo;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\ScripterDynamo.mdf" providerName="System.Data.SqlClient" />
<add name="conn1" connectionString="Server=Serv1;Database=db1;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
<add name="conn2" connectionString="Server=Serv2;Database=db2;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
<add name="conn3" connectionString="Server=Serv3;Database=db3;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
<add name="conn4" connectionString="Server=Serv4;Database=db4;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
</connectionStrings>
然后我像这样创建一个简单的上下文class
using ScripterEngine.Models;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
namespace ScripterEngine.DataAccessLayer
{
public class BaseContext : DbContext
{
public DbSet<Campaign> Campaign { get; set; }
public DbSet<TableMeta> Campaign { get; set; }
public BaseContext(string connectionName = "BaseConnection")
: base(connectionName)
{
}
}
}
使用此上下文 class 我可以像这样连接到 conn4
BaseConnection conn4 = BaseConnection("conn4");
这里唯一的问题是连接 "conn4" 将连接到连接字符串中默认设置的名为 db4 的数据库。在大多数情况下,这是预期的并且很好。但就我而言,我希望能够在 运行 时间更改要连接的数据库。
我的问题是,如何即时更改数据库?有没有办法在上下文 class 中添加一个方法,它只会覆盖默认数据库?
已更新
这是我更改上下文的内容 class 希望 setDatabase 方法允许我在 运行 时间更改数据库
using ScripterEngine.Models;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
namespace ScripterEngine.DataAccessLayer
{
public class BaseContext : DbContext
{
protected string connectionName;
public DbSet<Campaign> Campaign { get; set; }
public DbSet<TableMeta> TableMeta { get; set; }
public BaseContext(string connName = "BaseConnection")
: base(connName)
{
connectionName = connName;
}
public BaseContext setDatabase(string databaseName)
{
var connection = System.Configuration.ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;
//change the database before creating the new connection
return new BaseContext(connection);
}
}
}
我会这样使用它
BaseContext db1 = new BaseContext("conn4";
var connToNewDB = db1.setDatabase("SomeNewDatabase");
你可以这样做,这个 ExampleData 只是一个例子来理解,你可以在这里关联你需要的值,你的连接字符串保持这样:
<connectionStrings>
<add name="ConnectionString.Properties.Settings.CustomConnectionString"
connectionString="Persist Security Info=True" providerName="System.Data.SqlClient" />
</connectionStrings>
这只是初始化数据的例子
使用系统;
namespace ConnectionStringCustom
{
public static class ExampleData
{
public static String connUserName = "user";
public static String connPassword = "pass";
public static String connServerName = "servername";
public static String connDatabaseName = "databasename";
}
}
namespace ConnectionStringCustom.Properties
{
internal sealed partial class Settings
{
void Settings_SettingsLoaded( object sender, System.Configuration.SettingsLoadedEventArgs e )
{
this["CustomConnectionString"] = "Data Source=" + ExampleData.connServerName + ";"
+ "Initial Catalog=" + ExampleData.connDatabaseName + ";"
+ "Persist Security Info=false;"
+ "User ID=" + ExampleData.strConnUserName + ";"
+ "Password=" + ExampleData.connPassword + ";";
}
}
}
有了这个你可以改变所有的属性。
编辑:
查看您的更改,我认为您可能需要类似
的内容
但我认为这不是一个好的做法,为什么不简单地创建许多 ConnectionString?
希望对您有所帮助
尝试设置DbConnection.ConnectionString属性.
dataContextInstance.Database.Connection.ConnectionString = "new connection string";
但我不确定您是否需要在更改连接字符串后重新初始化某些 properties/code。
我创建了 2 个上下文。
BaseContext:这个上下文不会改变,我用它来设计我的应用程序,使用代码优先方法。
DynamicContext:此上下文将在 运行 时间更改。
为了让 DynamicContext 工作,我在我的连接文件中创建了一个动态连接。
我基本上把它添加到了我的区块中
<add name="DynamicConnection" connectionString="Server=DefaultServer;Initial Catalog=I3_IC;User ID=defaultUser; Password=defaultPassword;" providerName="System.Data.SqlClient" />
然后我像这样创建了一个新的上下文class
使用系统;
使用 System.Collections.Generic;
使用 System.Data.Common;
使用 System.Data.Entity;
使用 System.Data.Entity.Core.EntityClient;
使用 System.Data.SqlClient;
使用 System.Linq;
使用 System.Web;
namespace MyApp.DataAccessLayer
{
public class DynamicContext : DbContext
{
protected string connectionName = "DynamicConnection";
protected string myServerName;
protected string myUserId;
protected string myPassword;
/**
* Created the connection to the server using the giving connection string name.
* This constructor will allow you to connect to any connection string found in the Web.config file
*
* @param connName
*/
public DynamicContext(string serverName = null, string userID = null, string password = null)
: base("DynamicConnection")
{
myServerName = serverName;
myUserId = userID;
myPassword = password;
}
/**
* This constructor will allow you to construct a context by giving a string and it can only be call from the class itself
*
*/
private DynamicContext(string connectionString)
: base(connectionString)
{
}
/**
* Changes the default database
*
* @param databaseName
*/
public DynamicContext setDatabase(string databaseName)
{
//Get the existing string for dynamic connection
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;
//convert the existsing string into an object
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString);
//change the database before creating the new connection
builder.InitialCatalog = databaseName;
if (myServerName != null){
builder.DataSource = myServerName;
}
if (myUserId != null){
builder.UserID = myUserId;
}
if (myPassword != null){
builder.Password = myPassword;
}
return new DynamicContext(builder.ConnectionString);
}
}
}
那我就这样用
//Create a dynamic context, note that you can also change the username and the password of the default user by using the second and third parameters.
var dbDynamic = new DynamicContext(serverName);
//Finally, you can set the correct table
var conn1 = dbDynamic.setDatabase('table1');
//If you want to connect to a different table
var conn2 = dbDynamic.setDatabase('table2');
我有一个上下文 class,它将在构造函数中接受一个连接名称。然后它允许我连接到特定的服务器。
我想知道如何在 运行 时更改该连接的默认数据库。
这是我所做的
在 Web.config 文件中,我添加了以下连接字符串
<connectionStrings>
<add name="BaseConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ScripterDynamo;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\ScripterDynamo.mdf" providerName="System.Data.SqlClient" />
<add name="conn1" connectionString="Server=Serv1;Database=db1;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
<add name="conn2" connectionString="Server=Serv2;Database=db2;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
<add name="conn3" connectionString="Server=Serv3;Database=db3;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
<add name="conn4" connectionString="Server=Serv4;Database=db4;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
</connectionStrings>
然后我像这样创建一个简单的上下文class
using ScripterEngine.Models;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
namespace ScripterEngine.DataAccessLayer
{
public class BaseContext : DbContext
{
public DbSet<Campaign> Campaign { get; set; }
public DbSet<TableMeta> Campaign { get; set; }
public BaseContext(string connectionName = "BaseConnection")
: base(connectionName)
{
}
}
}
使用此上下文 class 我可以像这样连接到 conn4
BaseConnection conn4 = BaseConnection("conn4");
这里唯一的问题是连接 "conn4" 将连接到连接字符串中默认设置的名为 db4 的数据库。在大多数情况下,这是预期的并且很好。但就我而言,我希望能够在 运行 时间更改要连接的数据库。
我的问题是,如何即时更改数据库?有没有办法在上下文 class 中添加一个方法,它只会覆盖默认数据库?
已更新
这是我更改上下文的内容 class 希望 setDatabase 方法允许我在 运行 时间更改数据库
using ScripterEngine.Models;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
namespace ScripterEngine.DataAccessLayer
{
public class BaseContext : DbContext
{
protected string connectionName;
public DbSet<Campaign> Campaign { get; set; }
public DbSet<TableMeta> TableMeta { get; set; }
public BaseContext(string connName = "BaseConnection")
: base(connName)
{
connectionName = connName;
}
public BaseContext setDatabase(string databaseName)
{
var connection = System.Configuration.ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;
//change the database before creating the new connection
return new BaseContext(connection);
}
}
}
我会这样使用它
BaseContext db1 = new BaseContext("conn4";
var connToNewDB = db1.setDatabase("SomeNewDatabase");
你可以这样做,这个 ExampleData 只是一个例子来理解,你可以在这里关联你需要的值,你的连接字符串保持这样:
<connectionStrings>
<add name="ConnectionString.Properties.Settings.CustomConnectionString"
connectionString="Persist Security Info=True" providerName="System.Data.SqlClient" />
</connectionStrings>
这只是初始化数据的例子 使用系统;
namespace ConnectionStringCustom
{
public static class ExampleData
{
public static String connUserName = "user";
public static String connPassword = "pass";
public static String connServerName = "servername";
public static String connDatabaseName = "databasename";
}
}
namespace ConnectionStringCustom.Properties
{
internal sealed partial class Settings
{
void Settings_SettingsLoaded( object sender, System.Configuration.SettingsLoadedEventArgs e )
{
this["CustomConnectionString"] = "Data Source=" + ExampleData.connServerName + ";"
+ "Initial Catalog=" + ExampleData.connDatabaseName + ";"
+ "Persist Security Info=false;"
+ "User ID=" + ExampleData.strConnUserName + ";"
+ "Password=" + ExampleData.connPassword + ";";
}
}
}
有了这个你可以改变所有的属性。
编辑: 查看您的更改,我认为您可能需要类似
的内容但我认为这不是一个好的做法,为什么不简单地创建许多 ConnectionString?
希望对您有所帮助
尝试设置DbConnection.ConnectionString属性.
dataContextInstance.Database.Connection.ConnectionString = "new connection string";
但我不确定您是否需要在更改连接字符串后重新初始化某些 properties/code。
我创建了 2 个上下文。
BaseContext:这个上下文不会改变,我用它来设计我的应用程序,使用代码优先方法。
DynamicContext:此上下文将在 运行 时间更改。
为了让 DynamicContext 工作,我在我的连接文件中创建了一个动态连接。
我基本上把它添加到了我的区块中
<add name="DynamicConnection" connectionString="Server=DefaultServer;Initial Catalog=I3_IC;User ID=defaultUser; Password=defaultPassword;" providerName="System.Data.SqlClient" />
然后我像这样创建了一个新的上下文class
使用系统; 使用 System.Collections.Generic; 使用 System.Data.Common; 使用 System.Data.Entity; 使用 System.Data.Entity.Core.EntityClient; 使用 System.Data.SqlClient; 使用 System.Linq; 使用 System.Web;
namespace MyApp.DataAccessLayer
{
public class DynamicContext : DbContext
{
protected string connectionName = "DynamicConnection";
protected string myServerName;
protected string myUserId;
protected string myPassword;
/**
* Created the connection to the server using the giving connection string name.
* This constructor will allow you to connect to any connection string found in the Web.config file
*
* @param connName
*/
public DynamicContext(string serverName = null, string userID = null, string password = null)
: base("DynamicConnection")
{
myServerName = serverName;
myUserId = userID;
myPassword = password;
}
/**
* This constructor will allow you to construct a context by giving a string and it can only be call from the class itself
*
*/
private DynamicContext(string connectionString)
: base(connectionString)
{
}
/**
* Changes the default database
*
* @param databaseName
*/
public DynamicContext setDatabase(string databaseName)
{
//Get the existing string for dynamic connection
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;
//convert the existsing string into an object
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString);
//change the database before creating the new connection
builder.InitialCatalog = databaseName;
if (myServerName != null){
builder.DataSource = myServerName;
}
if (myUserId != null){
builder.UserID = myUserId;
}
if (myPassword != null){
builder.Password = myPassword;
}
return new DynamicContext(builder.ConnectionString);
}
}
}
那我就这样用
//Create a dynamic context, note that you can also change the username and the password of the default user by using the second and third parameters.
var dbDynamic = new DynamicContext(serverName);
//Finally, you can set the correct table
var conn1 = dbDynamic.setDatabase('table1');
//If you want to connect to a different table
var conn2 = dbDynamic.setDatabase('table2');