2011-10-03 61 views
11

我正在開發一個簡單的軟件,該軟件首先使用Entity Framework代碼和sql server compact 4.此時此安裝程序有效。如果尚未存在,則實體框架將創建sql server精簡文件。數據庫的路徑是從存儲在app.config文件內的連接字符串中定義的。它是建立這樣的:在appdata文件夾中創建sql server compact文件

<connectionStrings> 
    <add name="DataContext" 
     connectionString="Data source=Database.sdf;" 
     providerName="System.Data.SqlServerCe.4.0"/> 
</connectionStrings> 

不過,我想將數據庫中的當前用戶的Application Data文件夾內的文件夾中(在C:\用戶\用戶\應用程序數據\我的win7機器上漫遊文件夾) 。我已經嘗試將連接字符串的數據源設置爲%APPDATA%\ Database.sdf,但這不起作用,我得到「路徑中的非法字符」異常。

我想堅持connectionstring方法,因爲我想爲我的單元測試使用不同的數據庫,而不是我的實際應用程序。這樣,通過在項目的根目錄中放置一個app.config文件來修改數據庫很容易。

有人可以引導我在正確的方向嗎?下面

+0

但是這種方式我必須在代碼中構建連接字符串。這不會讓我們很容易切換數據庫的位置,就像我現在做的那樣。我在我的常規項目和我的測試項目中都有一個單獨的app.config文件,它們都指向不同的數據庫。 –

回答

22

用途:

AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); 

<connectionStrings> 
    <add name="DataContext" 
     connectionString="Data source=|DataDirectory|Database.sdf;" 
     providerName="System.Data.SqlServerCe.4.0"/> 
</connectionStrings> 
+0

謝謝,這個工程。實際的應用程序是一個wpf應用程序,我將AppDomain行放在App.xaml.cs啓動方法中。 –

+0

不客氣。 –

+4

您需要在「DataDirectory」(| DataDirectory |)之前添加另一個管道。只是認爲這可能會幫助別人,因爲我被困在了一段時間! http://msdn.microsoft.com/en-us/library/cc716756(v=vs.100).aspx – Rachel

3
connectionString="Data source=Database.sdf;" 

這告訴你的應用程序尋找Database.sdf在應用程序的當前工作目錄;這可能在任何地方,也可能不是可寫的。你需要看看在您指定位置:

connectionString="Data source=|DataDirectory|Database.sdf;" 

ADO.NET查找管道符在連接字符串,並將其擴展到該名稱的應用程序的域的屬性的值。那麼DataDirectory屬性的價值是什麼?它應該由無論部署您的應用程序設置:

  • .MSI安裝程序將其設置爲應用程序安裝文件夾。如果您允許用戶選擇安裝文件夾,他們也選擇DataDirectory。這就是爲什麼你應該總是使用|DataDirectory|而不是硬編碼的路徑。
  • ClickOnce在您的項目中定義了一個特殊的數據文件夾。
  • Web應用程序使用App_Data文件夾。
  • Visual Studio調試器使用調試文件夾。

項目中任何具有「複製到輸出目錄」屬性的Visual Studio文件都將被複制到DataDirectory中。在大多數情況下,DataDirectory將是隻讀文件夾。如果你的數據是隻讀的,這很好,但如果你想寫入它,你將不得不將數據複製到可寫位置。最好的地方可能是Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData))。有這樣做的幾種方法:

  • 如果要創建一個空的新的數據文件,只需使用您的API標準CREATE DATABASEnew SqlCeConnection()或什麼的。
  • 如果您想從預先填充的種子或入門數據庫開始,請將種子數據庫包含在您的項目中。在應用程序啓動時,檢查數據庫是否存在於SpecialFolder.ApplicationData文件夾中,如果沒有,請將其複製到那裏。

如果您在網上搜索創建本地數據庫的示例代碼,您會遇到很多不好的建議。不要做以下事情:

new SqlCeConnection(@"Data source=c:\users\me\myApp\Database.sdf;"); // Do NOT do this! 

我希望我不必解釋爲什麼硬編碼數據的路徑是錯誤的;但請注意,除非您在連接字符串中指定完整路徑,否則該路徑與您當前的工作目錄相關。

using (var conn = new SqlCeConnection(@"Data source=|DataDirectory|Database.sdf;")) 
{ 
    conn.Open(); 
    // No No No! This throws an Access Exception for Standard users, 
    // and gets deleted when you repair the app! 
    var cmd = conn.CreateCommand("INSERT INTO Table (column1, column2) VALUES (@p1, @p2)"); 
    ... 
} 

不要試圖修改DataDirectory中的數據。這個目錄不僅總是可以由用戶修改,而是由安裝者擁有,而不是由用戶擁有。修復或卸載應用程序將刪除所有用戶的數據;用戶不喜歡那樣。相反,將安裝的數據複製到用戶可寫入的文件夾中,並對副本進行所有更改。

AppDomain.CurrentDomain.SetData("DataDirectory", 
    // Wrong, this overwrites where the user installed your app! 
    Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); 

在你的代碼不要更改DataDirectory的價值,它是由安裝程序設置,如果你改變它,你會不知道被安裝在您的數據在哪裏。如果你正在創建一個空的數據庫,只需在你的最終位置打開它。如果要製作副本,請打開已安裝的數據庫,將其保存到用戶位置,關閉已安裝的數據庫並打開副本。我也不鼓勵將數據保存到Environment.SpecialFolder.CommonApplicationData。這可能不是用戶可寫的,除非有非常好的理由,所有用戶必須被允許更改其他用戶的數據,否則每個用戶都應該擁有自己的數據庫。

相關問題