我们处于混合环境中,我们的应用程序同时使用ADO.NET和实体框架
由于两者都指向相同的物理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),那么它会抛出错误"上下文正在Code First模式中使用,该代码是从EDMX文件为数据库生成的First或Model First开发。"
我没有使用Code First。
https://msdn.microsoft.com/en-us/data/jj680699
这里讨论了EF 6中的代码库配置,但文章没有显示任何实际更改连接字符串的代码。
更新:有助于澄清我的问题的更多信息。
我不是先使用代码,而是想在配置文件之外构建一个连接字符串
我正在使用的DbContext是T4模板生成的自动生成的DbContext文件的部分类。
我的印象是我需要创建一个继承的DbConfiguration类并在该类中执行某些操作,但我找到的唯一示例是使用Azure。
https://msdn.microsoft.com/en-us/data/jj680699
有一篇关于Code Project的文章讨论了在运行时设置连接字符串,但本文基于每次创建新的Entity容器时构建连接字符串。
http://www.codeproject.com/Tips/234677/Set-the-connection-string-for-Entity-Framework-at
我希望能够使用我的部分DbContext类来创建连接字符串,以便调用者不必执行任何特殊操作。
更新:RunTime的工作代码,但不是DesignTime的工作代码
使用@Circular Reference"下面列出的代码",我能够更改连接字符串而不更改对我的Entity类的调用但是这对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正常工作,那就更好了。
答案 0 :(得分:21)
您可以使用配置文件中的连接字符串在设计时工作。
<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" />
所以不要删除它,因为只在设计时才需要它。
使用此方法(类似于上一个方法)在运行时以动态方式工作:
扩展数据上下文分部类:
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);
Ciao; - )
答案 1 :(得分:13)
您将获得Code First模式异常,因为您传递的是使用ADO.NET连接字符串构建的DbConnection
。此连接字符串不包含对元数据文件的引用,因此EntityFramework不知道在哪里找到它们。
要使用适当的编程设置连接字符串创建DbContext
,请使用EntityConnectionStringBuilder类。
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);
答案 2 :(得分:0)
另一种方法是在配置文件中声明另一个连接字符串,并将其与以下替代构造函数一起使用:
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");