Entity Framework 6 设置连接字符串运行时
Entity Framework 6 set connection string runtime
我们处于混合环境中,我们的应用程序同时使用 ADO.NET 和 Entity Framework。
由于两者都指向同一个物理 SQL 服务器,我们想从配置文件中删除 Entity Framework 连接字符串,然后根据当前 ADO.NET 连接字符串自动构建该字符串。
这避免了开发人员更改 ADO.NET 字符串但忘记更改 Entity Framework 连接字符串的错误。
我已阅读此内容,但他们没有回答问题。
How do I create connection string programmatically to MS SQL in Entity Framework 6?
如果我创建自己的 DbConnection 并将其传递给 DbContext(existingConnection, contextOwnsConnection) 然后它会抛出错误 "The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development."
我没有使用 Code First。
https://msdn.microsoft.com/en-us/data/jj680699
本文讨论了 EF 6 中的代码库配置,但本文未显示任何实际更改连接字符串的代码。
更新:帮助澄清我的问题的更多信息。
我不是先使用代码,而是想在配置文件之外构建连接字符串。
我使用的 DbContext 是 T4 模板正在生成的自动生成的 DbContext 文件的一部分 class。
我的印象是我需要创建一个继承的 DbConfiguration class 并在其中做一些事情 class 但我找到的唯一例子是使用 Azure。
https://msdn.microsoft.com/en-us/data/jj680699
Code Project 上有一篇文章讨论了在运行时设置连接字符串,但这篇文章是基于每次我创建一个新的实体容器时构建一个连接字符串。
http://www.codeproject.com/Tips/234677/Set-the-connection-string-for-Entity-Framework-at
我希望能够使用我的部分 DbContext class 来创建连接字符串,以便调用者不必执行任何特殊操作。
更新:运行时的工作代码但不是设计时的工作代码
使用@Circular Reference "listed below" 发布的代码,我能够在不更改对实体 class 的调用的情况下更改连接字符串,但这不适用于 DesignTime EDMX 文件。
public partial class TestEntities : DbContext
{
public TestEntities() : base(GetSqlConnection(), true)
{
}
public static DbConnection GetSqlConnection()
{
// Initialize the EntityConnectionStringBuilder.
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
var connectionSettings = ConfigurationManager.ConnectionStrings("Current_ADO_Connection_In_Config");
// Set the provider name.
entityBuilder.Provider = connectionSettings.ProviderName;
// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = connectionSettings.ConnectionString;
// Set the Metadata location.
entityBuilder.Metadata = "res://*/Models.TestModel.csdl|res://*/Models.TestModel.ssdl|res://*/Models.TestModel.msl";
return new EntityConnection(entityBuilder.ToString());
}
}
现在,如果我能让 DesignTime 工作,那就太好了。
您收到 Code First 模式异常,因为您正在传递使用 ADO.NET 连接字符串构建的 DbConnection
。此连接字符串不包含对元数据文件的引用,因此 EntityFramework 不知道在哪里可以找到它们。
要使用适当的编程设置连接字符串创建 DbContext
,请使用 EntityConnectionStringBuilder class。
var entityBuilder = new EntityConnectionStringBuilder();
// use your ADO.NET connection string
entityBuilder.ProviderConnectionString = conString;
// Set the Metadata location.
entityBuilder.Metadata = @"res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl";
var dbContext = new DbContext(entityBuilder.ConnectionString);
您可以在设计时使用配置文件中的连接字符串进行工作。
<add name="DWContext" connectionString="metadata=res://*/Database.DWH.DWModel.csdl|res://*/Database.DWH.DWModel.ssdl|res://*/Database.DWH.DWModel.msl;provider=System.Data.SqlClient;provider connection string="data source=SQLSERVER_INSTANCE;initial catalog=DB_NAME;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
所以不要删除它,因为您只在设计时需要它。
使用这种方法(类似于您的上一个方法)在运行时以动态方式工作:
扩展数据上下文部分class:
public partial class DWContext
{
public DWContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
/// <summary>
/// Create a new EF6 dynamic data context using the specified provider connection string.
/// </summary>
/// <param name="providerConnectionString">Provider connection string to use. Usually a standart ADO.NET connection string.</param>
/// <returns></returns>
public static DWContext Create(string providerConnectionString)
{
var entityBuilder = new EntityConnectionStringBuilder();
// use your ADO.NET connection string
entityBuilder.ProviderConnectionString = providerConnectionString;
entityBuilder.Provider = "System.Data.SqlClient";
// Set the Metadata location.
entityBuilder.Metadata = @"res://*/Database.DWH.DWModel.csdl|res://*/Database.DWH.DWModel.ssdl|res://*/Database.DWH.DWModel.msl";
return new DWContext(entityBuilder.ConnectionString);
}
}
然后从您的代码创建一个新的 EF 数据上下文:
private DWContext db = DWContext.Create(providerConnectionString);
再见 ;-)
其他方法是在配置文件中声明另一个连接字符串,并将其与以下替代构造函数一起使用:
class TestEntities : DbConnect {
public TestEntities (string connectionName)
: base($"name={connectionName}")
{
}
...
然后使用这个解决方案:
- 向配置文件添加另一个连接:
<add name="other" connectionString="metadata=res://*/Data.TestEntities .csdl|res://*/Data.TestEntities .ssdl|res://*/Data.TestEntities .msl;provider=System.Data.SqlClient;provider connection string="data source=...;initial catalog=...;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
这样称呼它:
var db = new TestEntities (connectionName:"other");
我们处于混合环境中,我们的应用程序同时使用 ADO.NET 和 Entity Framework。
由于两者都指向同一个物理 SQL 服务器,我们想从配置文件中删除 Entity Framework 连接字符串,然后根据当前 ADO.NET 连接字符串自动构建该字符串。
这避免了开发人员更改 ADO.NET 字符串但忘记更改 Entity Framework 连接字符串的错误。
我已阅读此内容,但他们没有回答问题。
How do I create connection string programmatically to MS SQL in Entity Framework 6?
如果我创建自己的 DbConnection 并将其传递给 DbContext(existingConnection, contextOwnsConnection) 然后它会抛出错误 "The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development."
我没有使用 Code First。
https://msdn.microsoft.com/en-us/data/jj680699
本文讨论了 EF 6 中的代码库配置,但本文未显示任何实际更改连接字符串的代码。
更新:帮助澄清我的问题的更多信息。
我不是先使用代码,而是想在配置文件之外构建连接字符串。
我使用的 DbContext 是 T4 模板正在生成的自动生成的 DbContext 文件的一部分 class。
我的印象是我需要创建一个继承的 DbConfiguration class 并在其中做一些事情 class 但我找到的唯一例子是使用 Azure。
https://msdn.microsoft.com/en-us/data/jj680699
Code Project 上有一篇文章讨论了在运行时设置连接字符串,但这篇文章是基于每次我创建一个新的实体容器时构建一个连接字符串。
http://www.codeproject.com/Tips/234677/Set-the-connection-string-for-Entity-Framework-at
我希望能够使用我的部分 DbContext class 来创建连接字符串,以便调用者不必执行任何特殊操作。
更新:运行时的工作代码但不是设计时的工作代码
使用@Circular Reference "listed below" 发布的代码,我能够在不更改对实体 class 的调用的情况下更改连接字符串,但这不适用于 DesignTime EDMX 文件。
public partial class TestEntities : DbContext
{
public TestEntities() : base(GetSqlConnection(), true)
{
}
public static DbConnection GetSqlConnection()
{
// Initialize the EntityConnectionStringBuilder.
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
var connectionSettings = ConfigurationManager.ConnectionStrings("Current_ADO_Connection_In_Config");
// Set the provider name.
entityBuilder.Provider = connectionSettings.ProviderName;
// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = connectionSettings.ConnectionString;
// Set the Metadata location.
entityBuilder.Metadata = "res://*/Models.TestModel.csdl|res://*/Models.TestModel.ssdl|res://*/Models.TestModel.msl";
return new EntityConnection(entityBuilder.ToString());
}
}
现在,如果我能让 DesignTime 工作,那就太好了。
您收到 Code First 模式异常,因为您正在传递使用 ADO.NET 连接字符串构建的 DbConnection
。此连接字符串不包含对元数据文件的引用,因此 EntityFramework 不知道在哪里可以找到它们。
要使用适当的编程设置连接字符串创建 DbContext
,请使用 EntityConnectionStringBuilder class。
var entityBuilder = new EntityConnectionStringBuilder();
// use your ADO.NET connection string
entityBuilder.ProviderConnectionString = conString;
// Set the Metadata location.
entityBuilder.Metadata = @"res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl";
var dbContext = new DbContext(entityBuilder.ConnectionString);
您可以在设计时使用配置文件中的连接字符串进行工作。
<add name="DWContext" connectionString="metadata=res://*/Database.DWH.DWModel.csdl|res://*/Database.DWH.DWModel.ssdl|res://*/Database.DWH.DWModel.msl;provider=System.Data.SqlClient;provider connection string="data source=SQLSERVER_INSTANCE;initial catalog=DB_NAME;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
所以不要删除它,因为您只在设计时需要它。
使用这种方法(类似于您的上一个方法)在运行时以动态方式工作:
扩展数据上下文部分class:
public partial class DWContext
{
public DWContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
/// <summary>
/// Create a new EF6 dynamic data context using the specified provider connection string.
/// </summary>
/// <param name="providerConnectionString">Provider connection string to use. Usually a standart ADO.NET connection string.</param>
/// <returns></returns>
public static DWContext Create(string providerConnectionString)
{
var entityBuilder = new EntityConnectionStringBuilder();
// use your ADO.NET connection string
entityBuilder.ProviderConnectionString = providerConnectionString;
entityBuilder.Provider = "System.Data.SqlClient";
// Set the Metadata location.
entityBuilder.Metadata = @"res://*/Database.DWH.DWModel.csdl|res://*/Database.DWH.DWModel.ssdl|res://*/Database.DWH.DWModel.msl";
return new DWContext(entityBuilder.ConnectionString);
}
}
然后从您的代码创建一个新的 EF 数据上下文:
private DWContext db = DWContext.Create(providerConnectionString);
再见 ;-)
其他方法是在配置文件中声明另一个连接字符串,并将其与以下替代构造函数一起使用:
class TestEntities : DbConnect {
public TestEntities (string connectionName)
: base($"name={connectionName}")
{
}
...
然后使用这个解决方案:
- 向配置文件添加另一个连接:
<add name="other" connectionString="metadata=res://*/Data.TestEntities .csdl|res://*/Data.TestEntities .ssdl|res://*/Data.TestEntities .msl;provider=System.Data.SqlClient;provider connection string="data source=...;initial catalog=...;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
这样称呼它:
var db = new TestEntities (connectionName:"other");