2015-04-03 66 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

相關問題