由於在產品開發中使用了EntityFramework,而Release給使用者安裝的資料庫有可能會因為使用者的關係而有所異動,因此考量此一問題,因此要提供給使用者修改Config中的EntityFramework的功能,然而看了許多的資料,發現要建立EntityFramework的ConnectionString格式的內容不難,要修改App.config的設定也不難,但是這兩件事要同時完成就有需要注意的地方。
先說說我的實作方法:
1. 透過 SqlConnectionStringBuilder 將使用者所設定的值串成 SqlConnectionString
builder = new SqlConnectionStringBuilder();
builder.DataSource = serverIP + "\\" + instanceName;
builder.InitialCatalog = dataBaseName;
builder.UserID = userID;
builder.Password = password;
builder.MultipleActiveResultSets = true;
builder.ApplicationName = "EntityFramework";
2.透過EntityConnectionStringBuilder將SqlConnectionString加上Metadata跟Provider設定變成 EntityConnectionString
EntityConnectionStringBuilder entBuilder = new EntityConnectionStringBuilder();
//一定要設定
entBuilder.Provider = "System.Data.SqlClient";
entBuilder.ProviderConnectionString = ConnectionString;
//要根據Model名稱設定
entBuilder.Metadata = @"res://*/dataModel.csdl|res://*/dataModel.ssdl|res://*/dataModel.msl";
3. 將App.Config檔範本變成Template且設定為內嵌資源然後取出Template置換EntityConnectionString然後將檔案寫入
//取得設定檔名(在此由於是獨立的類別專案)所以取到的名稱是[專案名稱.dll.config]
string configFile = string.Concat(Assembly.GetExecutingAssembly().Location, ".config");
//取得檔案資訊
FileInfo fileInfo = new FileInfo(configFile);
//取得執行檔的檔案所在目錄(這個才是真的需要的資訊)
string fileFolder = fileInfo.FullName.Replace(fileInfo.Name, string.Empty);
//取得內嵌資源的內容並轉為文字串
CommonHelpers commHelper = new CommonHelpers();
string originalText = commHelper.GetConfigText("Connection.conf");
//取代內嵌資源的內容並替換{EF_ConnString}成為EntityConnectionString
originalText = originalText.Replace("{EF_ConnString}", EntityConnectionString.Replace("\"", """));
//將檔案存回程式執行的目錄中執行檔案app.config
string path = Path.Combine(fileFolder, "SystemLead.Project.EINV.Win.exe.config");
System.IO.File.WriteAllText(path, originalText);
以下注意、
當EntityConnectionString要被替換到範本檔中時,可能有人注意到我使用了EntityConnectionString.Replace("\"", """),那是因為如果你直接用EntityConnectionString去寫到設定檔時會發生設定值變成:
<add name="eInvDBEntities"
connectionString="metadata=res://*/dataModel.csdl|res://*/dataModel.ssdl|res://*/dataModel.msl;
provider=System.Data.SqlClient;
provider connection string="data source=localhost\SL_APPDB;
initial catalog=ClientDB;
user id=myUser;
password=myPassword;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
乍看之下好像沒什麼問題,其實問題才大哩,真正透過產生出來的值應該是這樣:
<add name="eInvDBEntities"
connectionString="metadata=res://*/dataModel.csdl|res://*/dataModel.ssdl|res://*/dataModel.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=localhost\SL_APPDB;
initial catalog=ClientDB;
user id=myUser;
password=myPassword;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
仔細比較就會發現,在data source之前有一個[ " ]App=EntityFramework之後有一組[ "" ],這會讓整個設定值無法使用,所以必須要將多餘的[ " ]換成[ " ]才能正確執行,置換的時間點就是把{EF_ConnString}替換成EntityConnectionString的時候。
參考資源:
留言