Entity Framework(代码优先到现有数据库)- 在运行时覆盖 app.config 中的连接字符串
Entity Framework(Code First to an existing database) - overwrite a connection string in app.config at runtime
我需要将我的应用程序(windows 表单)动态连接到 SQL 服务器数据库,并且我在 app.config 中有 3 个连接字符串(其中 1 个我想要动态变化)。
下面是 app.config:
<connectionStrings>
<add name="NfceConnPortalInterno"
providerName="System.Data.SqlClient"
connectionString="Data Source=lab;Initial Catalog=portal;Persist Security Info=True;User ID=micportal;Password=150302;language=us_english"/>
<add name="NfceConnPortalExterno"
providerName="System.Data.SqlClient"
connectionString="Data Source=10.10.0.1,8081;Initial Catalog=portal;Persist Security Info=True;User ID=micportal;Password=\-W?98xpT;language=us_english"/>
<!-- this one will be modified in runtime. -->
<add
name="NfceContext"
connectionString="data source=(localdb)\v11.0;initial catalog=Blogging;Connection Timeout=320;Persist Security Info=True;integrated security=True;language=us_english;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>
在我的 DbContext 中我有这个:
public NfceContext() : base("name=NfceContext")
{
}
我正在尝试使用 AppDomain.CurrentDomain.SetupInformation.ConfigurationFile 在 class 中更改此 connectionString 的方法。如果我在调试模式下检查 运行,app.vshost.exe.config 上的 connectionStrings 会更改,但 app.config 不会(我猜应该修改 app.config)。
当我尝试做一个例子时:context.MyEntity.ToList(),它给了我这样的错误"you don´t have permission to create table...",如果我此时检查连接字符串,它是旧的(在我修改之前)。
下面的代码可以显示我所说的:
覆盖app.config中的连接字符串的方法:
private void ModifyNfceContext(string dataSource, string portal, string senha)
{
XmlDocument xml = new XmlDocument();
xml.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
XmlNodeList lista = xml.DocumentElement.SelectNodes(String.Format("connectionStrings/add [@name='{0}']", "NfceContext"));
XmlNode node = lista[0];
string connectionString = node.Attributes["connectionString"].Value;
SqlConnectionStringBuilder connStringBuilder = new SqlConnectionStringBuilder(connectionString);
connStringBuilder.InitialCatalog = portal;
connStringBuilder.DataSource = dataSource;
connStringBuilder.IntegratedSecurity = true;
connStringBuilder.UserID = "mic" + portal;
connStringBuilder.Password = senha;
node.Attributes["connectionString"].Value = connStringBuilder.ConnectionString;
xml.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
}
控制器的构造函数:
public NfceController()
{
if (this.context == null)
{
ModifyNfceContext(this.dataSource, this.portal, this.senha);
//At this moment, the connectionString should be modified.
this.context = new NfceContext();
}
this.repositoryNfce = new RepositoryNfce(context);
}
所以,我做错了什么?我需要更改 app.config 而不是 vhost.config 吗?
我写过 this article 关于在运行时首先为数据库设置连接字符串。看看这个;即使在您的情况下,它也可能有用。
简而言之,您可以创建部分 class 以访问 DbContext 构造函数重载,该重载将连接字符串作为参数(来自我的文章的示例):
public partial class peopleEntities : DbContext
{
public peopleEntities(String connectionString)
: base(connectionString)
{
}
}
然后您可以使用 EntityConnectionStringBuilder 来构建和传递连接字符串(示例也来自我的文章):
EntityConnectionStringBuilder csb = new EntityConnectionStringBuilder();
csb.Metadata = "res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl";
csb.Provider = "System.Data.SqlServerCe.4.0";
csb.ProviderConnectionString = "data source=people.sdf";
String entityConnStr = csb.ToString();
如果您的 NfceContext 不是静态对象,您可以创建另一个将连接字符串名称作为参数的构造函数,如下所示:
public class NfceContext : DbContext{
public NfceContext (string appConfigConStrName) : base (appConfigConStrName) { }
}
否则,如果您的上下文是静态对象,我认为这是不好的做法,您可以编写 public 方法,该方法将在您的 NfceContext 中创建 DbContext 的新实例:
public class NfceContext : DbContext{
static NfceContext context;
public static NfceContext() {
context = new NfceContext();
}
public void ChangeDB(string appConfigConStr) {
context = new NfceContext(appConfigConStr);
}
}
我需要将我的应用程序(windows 表单)动态连接到 SQL 服务器数据库,并且我在 app.config 中有 3 个连接字符串(其中 1 个我想要动态变化)。
下面是 app.config:
<connectionStrings>
<add name="NfceConnPortalInterno"
providerName="System.Data.SqlClient"
connectionString="Data Source=lab;Initial Catalog=portal;Persist Security Info=True;User ID=micportal;Password=150302;language=us_english"/>
<add name="NfceConnPortalExterno"
providerName="System.Data.SqlClient"
connectionString="Data Source=10.10.0.1,8081;Initial Catalog=portal;Persist Security Info=True;User ID=micportal;Password=\-W?98xpT;language=us_english"/>
<!-- this one will be modified in runtime. -->
<add
name="NfceContext"
connectionString="data source=(localdb)\v11.0;initial catalog=Blogging;Connection Timeout=320;Persist Security Info=True;integrated security=True;language=us_english;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>
在我的 DbContext 中我有这个:
public NfceContext() : base("name=NfceContext")
{
}
我正在尝试使用 AppDomain.CurrentDomain.SetupInformation.ConfigurationFile 在 class 中更改此 connectionString 的方法。如果我在调试模式下检查 运行,app.vshost.exe.config 上的 connectionStrings 会更改,但 app.config 不会(我猜应该修改 app.config)。
当我尝试做一个例子时:context.MyEntity.ToList(),它给了我这样的错误"you don´t have permission to create table...",如果我此时检查连接字符串,它是旧的(在我修改之前)。
下面的代码可以显示我所说的:
覆盖app.config中的连接字符串的方法:
private void ModifyNfceContext(string dataSource, string portal, string senha)
{
XmlDocument xml = new XmlDocument();
xml.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
XmlNodeList lista = xml.DocumentElement.SelectNodes(String.Format("connectionStrings/add [@name='{0}']", "NfceContext"));
XmlNode node = lista[0];
string connectionString = node.Attributes["connectionString"].Value;
SqlConnectionStringBuilder connStringBuilder = new SqlConnectionStringBuilder(connectionString);
connStringBuilder.InitialCatalog = portal;
connStringBuilder.DataSource = dataSource;
connStringBuilder.IntegratedSecurity = true;
connStringBuilder.UserID = "mic" + portal;
connStringBuilder.Password = senha;
node.Attributes["connectionString"].Value = connStringBuilder.ConnectionString;
xml.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
}
控制器的构造函数:
public NfceController()
{
if (this.context == null)
{
ModifyNfceContext(this.dataSource, this.portal, this.senha);
//At this moment, the connectionString should be modified.
this.context = new NfceContext();
}
this.repositoryNfce = new RepositoryNfce(context);
}
所以,我做错了什么?我需要更改 app.config 而不是 vhost.config 吗?
我写过 this article 关于在运行时首先为数据库设置连接字符串。看看这个;即使在您的情况下,它也可能有用。
简而言之,您可以创建部分 class 以访问 DbContext 构造函数重载,该重载将连接字符串作为参数(来自我的文章的示例):
public partial class peopleEntities : DbContext
{
public peopleEntities(String connectionString)
: base(connectionString)
{
}
}
然后您可以使用 EntityConnectionStringBuilder 来构建和传递连接字符串(示例也来自我的文章):
EntityConnectionStringBuilder csb = new EntityConnectionStringBuilder();
csb.Metadata = "res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl";
csb.Provider = "System.Data.SqlServerCe.4.0";
csb.ProviderConnectionString = "data source=people.sdf";
String entityConnStr = csb.ToString();
如果您的 NfceContext 不是静态对象,您可以创建另一个将连接字符串名称作为参数的构造函数,如下所示:
public class NfceContext : DbContext{
public NfceContext (string appConfigConStrName) : base (appConfigConStrName) { }
}
否则,如果您的上下文是静态对象,我认为这是不好的做法,您可以编写 public 方法,该方法将在您的 NfceContext 中创建 DbContext 的新实例:
public class NfceContext : DbContext{
static NfceContext context;
public static NfceContext() {
context = new NfceContext();
}
public void ChangeDB(string appConfigConStr) {
context = new NfceContext(appConfigConStr);
}
}