前幾天遇到幾個 Entity Framework 的連線問題,因此誓死研究出前因後果,本次研究頗有心得,雖然都是小東西,但應該算蠻重要的,對日後用 Entity Framework 開發 DAL 元件有很大的幫助。
注意: 以下專案範例都是以 .NET 4.0 為示範,使用 .NET 3.5 可能會有不同的結果。
1. 記得加入 System.Data.Entity 參考組件
2. 在 ConsoleApp 使用 AdventureWorksLT.Model 專案的 EDMX 進行資料查詢
使用連線參數最簡單的作法就是將 App.config 直接複製到 ConsoleApp 專案使用
如果已經有 App.config 或 Web.config 的話,只要將 ConnectionStrings 內的設定複製過去即可!
若透過程式產生連線字串就有幾點需特別注意,首先在 DAL 專案中的 Entity Framework 連線參數如下:
<add name="AdventureWorksLTEntities" connectionString="metadata=res://*/AdventureWorksLT.csdl | res://*/AdventureWorksLT.ssd l | res://*/AdventureWorksLT.msl; provider=System.Data.SqlClient; provider connection string="Data Source=.\sqlexpress;Initial Catalog=AdventureWorksLT;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
上述連線參數最值得注意的地方是被標注紅色粗體的部分,在 metadata 屬性必須明確指出 CSDL、SSDL 與 MSL 三個檔案的位置,預設來說透過 Entity Framework 設計工具產生的 EDMX 檔的 [中繼資料成品處理] 屬性為 內嵌在輸出組件中 (如下圖示),所以當在 DAL 專案以外的地方要參考這三個檔案就必須修改 metadata 所指出的這三個檔案的路徑。
若你的 CSDL、SSDL 與 MSL 三個檔案是設定內嵌在輸出組件中,你就必須在設定 Entity Framework 連線參數時將上述 metadata 標注 * 的部分修改成組件名稱,這樣就能正確載入 Entity Framework 了,如下範例:
metadata=res://AdventureWorksLT.Model/AdventureWorksLT.csdl | res://AdventureWorksLT.Model/AdventureWorksLT.ssd l | res://AdventureWorksLT.Model/AdventureWorksLT.msl; provider=System.Data.SqlClient; provider connection string="Data Source=.\sqlexpress;Initial Catalog=AdventureWorksLT;Integrated Security=True;MultipleActiveResultSets=True"
實際建立連線參數的程式碼可參考以下程式片段:
static private string buildConnectString()
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = @".\SQLEXPRESS";
builder.ApplicationName = "";
builder.InitialCatalog = "AdventureWorksLT";
builder.IntegratedSecurity = true;
builder.PersistSecurityInfo = true;
EntityConnectionStringBuilder entBuilder = new EntityConnectionStringBuilder();
entBuilder.Provider = "System.Data.SqlClient";
entBuilder.ProviderConnectionString = builder.ConnectionString;
entBuilder.Metadata = @"res://AdventureWorksLT.Model/AdventureWorksLT.csdl|res://AdventureWorksLT.Model/AdventureWorksLT.ssdl|res://AdventureWorksLT.Model/AdventureWorksLT.msl";
return entBuilder.ConnectionString;
}
備註: 如果寫在 app.config 或 web.config 中是可以用 * 符號替代,但如果發生異常就需要換成組件名稱。
如果你將 [中繼資料成品處理] 屬性設定為 [複製到輸出目錄],就會在建置專案後將這三個檔案複製到預設輸出目錄:
你也可以將這三個檔案透過 Visual Studio 2010 [加入做為連結] 功能連結至要使用的專案:
加入連結後設定完成後,先選取這三個檔案,並按下 F4 開啟屬性視窗,並將 [複製到輸出目錄] 設定為 [有更新時才複製] 即可兩個專案共用同一組 Entity Framwork 產生的模型檔案:
專案編譯完成後的結果如下圖示:
最後一個步驟就是修改 app.config 的連線字串成如下 ( 請注意紅字部分組件所在目錄的相對路徑 )
metadata=./AdventureWorksLT.csdl | ./AdventureWorksLT.ssd l | ./AdventureWorksLT.msl; provider=System.Data.SqlClient; provider connection string="Data Source=.\sqlexpress;Initial Catalog=AdventureWorksLT;Integrated Security=True;MultipleActiveResultSets=True"
如果是 ASP.NET 環境下,就必須修改 web.config 中的連線參數如下 ( 請注意紅字部分相對於網站根目錄的 bin 目錄下,可使用 ~ 符號代表網站根目錄 )
metadata=~/bin/AdventureWorksLT.csdl | ~/bin/AdventureWorksLT.ssd l | ~/bin/AdventureWorksLT.msl; provider=System.Data.SqlClient; provider connection string="Data Source=.\sqlexpress;Initial Catalog=AdventureWorksLT;Integrated Security=True;MultipleActiveResultSets=True"
若連線參數沒有設定好而導致 Entity Framework 無法讀取 CSDL、SSDL 與 MSL 三個檔案時,就會出現的 Unable to load the specified metadata resource. 或 無法載入指定的中繼資料資源 的錯誤。
範例程式下載:AdventureWorksLT_EF_Sample.7z ( 註: 請用 7-Zip 解壓縮 )
相關連結