[英]Create sql server compact file in appdata folder
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代码,然后使用sql server compact 4.此时此设置正常工作。 Entity framework creates the sql server compact file if it doesn't yet exists.
实体框架创建sql server压缩文件(如果它尚不存在)。 The path to the database is defined from within a connectionstring which is stored inside the app.config file.
数据库的路径是从存储在app.config文件中的连接字符串中定义的。 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). 但是,我想将数据库放在当前用户的Application Data文件夹(我的win7机器上的C:\\ Users \\ User \\ AppData \\ Roaming文件夹)中的文件夹中。 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.
我已经尝试将connectionstring的数据源设置为%APPDATA%\\ Database.sdf,但是这不起作用,我得到了“路径中的非法字符”异常。
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. 我想坚持使用connectionstring方法,因为我想为我的单元测试使用不同的数据库而不是我的实际应用程序。 This way it is easy to modify the database by placing an app.config file in the root of the project.
这样,通过将app.config文件放在项目的根目录中,可以轻松地修改数据库。
Can someone steer me in the right direction? 有人能引导我朝着正确的方向前进吗?
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>
connectionString="Data source=Database.sdf;"
This tells your app to look for Database.sdf in your app's current working directory; 这告诉您的应用在应用的当前工作目录中查找Database.sdf; 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. ADO.NET在连接字符串中查找管道字符,并将它们扩展为应用程序域中该名称的属性值。 So what's the value of the
DataDirectory
property? 那么
DataDirectory
属性的价值是什么? It's supposed to be set by whatever deployed your application: 它应该由您部署的应用程序设置:
|DataDirectory|
|DataDirectory|
and never a hard-coded path. Any Visual Studio files in your project with a “copy to output directory” property will be copied to DataDirectory. 项目中具有“复制到输出目录”属性的任何Visual Studio文件都将复制到DataDirectory。 In most cases DataDirectory will be a read-only folder.
在大多数情况下,DataDirectory将是一个只读文件夹。 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))
. 可能最好的地方是
Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData))
。 There are several ways of doing this: 有几种方法可以做到这一点:
CREATE DATABASE
or new SqlCeConnection()
or whatever. CREATE DATABASE
或new SqlCeConnection()
或其他。 SpecialFolder.ApplicationData
folder and, if not, copy it there. SpecialFolder.ApplicationData
文件夹中是否存在数据库,如果不存在,则将其复制到该文件夹中。 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
. 不要尝试修改
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. 不要在代码中更改
DataDirectory
的值,它由安装程序设置,如果更改它,您将无法知道数据的安装位置。 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
. 我也不鼓励将数据保存到
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. 这可能是用户无法写入的,除非有非常好的理由必须允许所有用户更改其他用户的数据,否则每个用户都应拥有自己的数据库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.