2015-04-03 64 views
17

我们处于一个混合的环境中,我们的应用程序使用ADO.NET和实体框架。
由于两者都指向相同的物理SQL服务器,我们希望从配置文件中删除实体框架连接字符串,然后根据当前的ADO.NET连接字符串自动生成字符串。
这节省了我们的开发人员更改ADO.NET字符串但忘记更改实体框架连接字符串的错误。实体框架6设置连接字符串运行时间

我已经读过这个,但他们没有回答这个问题。
How do I create connection string programmatically to MS SQL in Entity Framework 6?

如果我创造我自己的DbConnection并传递到的DbContext(existingConnection,contextOwnsConnection),那么它抛出一个错误“的情况下被以代码优先模式下的代码是从一个EDMX文件生成的使用,也可以数据库优先或模型优先开发“。

我没有使用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的文章,讲述了在运行时设置连接字符串,但文章基于每次创建新实体容器时都创建连接字符串。
http://www.codeproject.com/Tips/234677/Set-the-connection-string-for-Entity-Framework-at

我想能够使用我的部分DbContext类创建连接字符串,以便调用者不必做任何特殊的事情。

更新:工作代码用于运行时间而不是设计时
使用张贴@Circular参考“下面列出的”代码,我能更改连接字符串,而不改变我的实体类的电话,但这个不起作用用于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

我想你会使用的ObjectContext inste DbContext的广告,因为您没有使用Code First。我不是100%确定这种关系。这提示:https://msdn.microsoft.com/en-us/library/bb738461(v=vs.110).aspx并从此处链接描述创建连接:https://msdn.microsoft.com /en-us/library/bb738533%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396 – AaronLS 2015-04-03 22:26:36

+0

CodeFirst的连接字符串通常是标准连接字符串,其中非CodeFirst的连接字符串通常是对csdl/ssdl/msl文件。 – AaronLS 2015-04-03 22:27:55

回答

10

由于您传递的是使用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); 
+0

你的答案有效,但我每次在代码中创建一个实体容器时都必须这样做。我需要在部分DbContext调用中执行此操作的一些方法...但即使如此,我不确定这对设计人员是否有效。我想我必须用DbConfiguration做些事情,但我找不到任何好的例子。 – goroth 2015-04-06 13:21:38

+0

检查[this](http://forums.asp.net/t/1747809.aspx?How+to+pass+in+an+entity+framework+connection+string+between+assemblies+)。你将不得不多写一些代码,并且在工作的同时,从可维护性的角度来看,这是不好的。将EF连接字符串保存在配置文件中可能会更好。 – 2015-04-06 17:51:51

+0

如果我可以开始工作,我会很满意这个实现。但是,当尝试访问由上述创建的数据库上下文数据库时,出现“关键字不支持”元数据“”错误。 – 2017-12-09 16:55:31

17

您可以在设计时使用配置文件中的连接字符串工作。

<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=&quot;data source=SQLSERVER_INSTANCE;initial catalog=DB_NAME;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" 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); 

侨;-)

+0

甜美简单的解决方案,谢谢:) – 2016-12-12 13:36:49

+0

这对我不起作用,我得到了“这个上下文在代码优先模式下使用...”的消息。 – 2017-08-24 17:48:05

+0

@NilsGuillermin尝试再次删除并创建数据模型,并确保选择“从现有数据库创建(数据库优先)”选项。 – jacktric 2017-08-25 07:42:35

相关问题