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

发布于 2024-12-08 05:18:02 字数 645 浏览 0 评论 0原文

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

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

但是,我想将数据库放置在当前用户的 Application Data 文件夹中的一个文件夹中(我的 win7 机器上的 C:\Users\User\AppData\Roaming 文件夹)。我尝试将连接字符串的数据源设置为 %APPDATA%\Database.sdf 之类的内容,但这不起作用,我收到“路径中的非法字符”异常。

我想坚持使用连接字符串方法,因为我想为单元测试使用与实际应用程序不同的数据库。这样,通过将 app.config 文件放置在项目的根目录中就可以轻松修改数据库。

有人可以引导我走向正确的方向吗?

I am developing a simple piece of software which uses Entity Framework code first and sql server compact 4. At the moment this setup works. Entity framework creates the sql server compact file if it doesn't yet exists. The path to the database is defined from within a connectionstring which is stored inside the app.config file. It is build up like this:

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

However, I want to place the database in a folder within the current user's Application Data folder (the C:\Users\User\AppData\Roaming folder on my win7 machine). I've tried setting the Data source of the connectionstring to something like %APPDATA%\Database.sdf, but this doesn't work, I get an "Illegal characters in path" exception.

I want to stick with the connectionstring method, because I'd like to use a different database for my unit tests than with my actual application. This way it is easy to modify the database by placing an app.config file in the root of the project.

Can someone steer me in the right direction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

万劫不复 2024-12-15 05:18:02

使用如下:

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>

Use below:

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>
水晶透心 2024-12-15 05:18:02
    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。用户可能无法写入该数据,除非有非常充分的理由必须允许所有用户更改其他用户的数据,否则每个用户都应该拥有自己的数据库。

    connectionString="Data source=Database.sdf;"

This tells your app to look for Database.sdf in your app’s current working directory; which could be anywhere and may not be writeable. You need to look at a location you specify:

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

ADO.NET looks for pipe characters in connection strings and expands them to the value of the property of that name in the application’s domain. So what’s the value of the DataDirectory property? It’s supposed to be set by whatever deployed your application:

  • .MSI installers set it to the app installation folder. If you allow the user to choose the installation folder, they choose the DataDirectory as well. This is why you should always use |DataDirectory| and never a hard-coded path.
  • ClickOnce defines a special data folder in your project.
  • Web apps use the App_Data folder.
  • The Visual Studio debugger uses the debug folder.

Any Visual Studio files in your project with a “copy to output directory” property will be copied to DataDirectory. In most cases DataDirectory will be a read-only folder. This is fine if your data is read-only, but if you want to write to it you will have to copy your data to a writeable location. Probably the best place is Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData)). There are several ways of doing this:

  • If you are creating an empty new data file, just use your API’s standard CREATE DATABASE or new SqlCeConnection() or whatever.
  • If you want to start with a pre-populated seed or starter database, include the seed database in your project . In your application startup, check if the database exists in the SpecialFolder.ApplicationData folder and, if not, copy it there.

If you search the web for sample code on creating local database you will run across a lot of bad advice. Do not do the following:

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

I hope I don’t have to explain why hard-coding the path to your data is wrong; but be aware that unless you specify a full path in your connection string, the path is relative to your current working directory.

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)");
    ...
}

Do not try to modify the data in DataDirectory. Not only is this directory not always modifiable by users, it is owned by the installer not by the user. Repairing or uninstalling the application will delete all the user’s data; users don’t like that. Instead, copy the installed data to a folder writable by the user and make all changes to the copy.

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

Do not change the value of DataDirectory in your code, it is set by the installer and if you change it you won’t know where your data was installed. If you are creating an empty database, just open it in your final location. If you are going to make a copy, open the installed database, save it to the user’s location, close the installed database, and open the copy.

I also discourage saving data to Environment.SpecialFolder.CommonApplicationData. This may not be writable by users, and unless there is a very very good reason all users must be allowed to change other users’ data, each user should have their own database.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文