在appdata文件夹中创建sql server压缩文件

本文关键字:server 压缩 文件 sql 创建 appdata 文件夹 | 更新日期: 2023-09-27 18:10:24

我正在开发一个简单的软件,它首先使用实体框架代码和sql server compact 4。目前,这种设置是有效的。实体框架创建sql server压缩文件(如果它还不存在(。数据库的路径是从存储在app.config文件中的连接字符串中定义的。它是这样建立的:

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

但是,我想将数据库放在当前用户的"应用程序数据"文件夹(我的win7计算机上的C:''Users''user''AppData''Roaming文件夹(中的一个文件夹中。我尝试将连接字符串的数据源设置为%APPDATA%''Database.sdf,但这不起作用,我得到了一个"路径中的非法字符"异常。

我想坚持使用connectionstring方法,因为我想在单元测试中使用与实际应用程序不同的数据库。这样,通过在项目的根目录中放置app.config文件可以很容易地修改数据库。

有人能引导我朝正确的方向走吗?

在appdata文件夹中创建sql server压缩文件

使用以下内容:

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>
    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。这可能是用户不可写的,除非有非常好的理由必须允许所有用户更改其他用户的数据,否则每个用户都应该有自己的数据库。