wpf 连接字符串中的 %APPDATA% 没有替换实际文件夹?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15037937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
%APPDATA% in connection string is not substituted for the actual folder?
提问by JSchwartz
When using WPF and entity-framework I have an APP.CONFIG that looks like the following:
使用 WPF 和实体框架时,我有一个 APP.CONFIG,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="DatabaseEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlServerCe.4.0;provider connection string="Data Source=%APPDATA%\Folder\Database.sdf"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
When using this code it always throws the following error:
使用此代码时,它总是会引发以下错误:
System.Data.EntityException: The underlying provider failed on Open. ---> System.Data.SqlServerCe.SqlCeException: The path is not valid. Check the directory for the database. [ Path = %APPDATA%\Folder\Database.sdf ]
When I run the path "%APPDATA%\Folder\Database.sdf" from the command prompt it works fine, and if I remove "%APPDATA% and hardcode the path it works fine - so it looks simply like the %APPDATA% is just not being substituted for the actual folder...
当我从命令提示符运行路径“%APPDATA%\Folder\Database.sdf”时它工作正常,如果我删除“%APPDATA%并对路径进行硬编码它工作正常 - 所以它看起来就像 %APPDATA% 是只是没有被替换为实际文件夹...
Thanks,
谢谢,
回答by Mohammad Dehghan
As you already reallized, %APPDATA%or any other environtment variables are not replaced with their respective value in connection strings. Environment varialbes are something related to the operating system shell. They work in command prompt because the command prompt explicitly parses the values entered and substitutes environment variables. That's not something that .NET Framwork usually performs.
正如您已经意识到的那样,%APPDATA%或者任何其他环境变量都不会替换为它们在连接字符串中各自的值。环境变量与操作系统外壳有关。它们在命令提示符下工作,因为命令提示符显式解析输入的值并替换环境变量。这不是 .NET Framework 通常执行的操作。
To achive this, you have to manually provide the value for %APPDATA%(using Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)or Environment.GetEnvironmentVariable("APPDATA")). There are two options:
要实现这一点,您必须手动提供%APPDATA%(使用Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)或Environment.GetEnvironmentVariable("APPDATA"))的值。有两种选择:
Change your connection string and use
|DataDirectory|:<connectionStrings> <add name="DatabaseEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlServerCe.4.0;provider connection string="Data Source=|DataDirectory|\Database.sdf"" providerName="System.Data.EntityClient" /> </connectionStrings>(Notice the use of
|DataDirectory|in the path to the database file.)Then provide the value for
|DataDirectory|in your application's Main method:AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));Refer to this MSDN page for more information.
Manually provide the connection string for your ObjectContext class. This way you can parse and change the connection string:
public static string GetConnectionString() { var conStr = System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseEntities"].ConnectionString; return conStr.Replace("%APPDATA%", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)); }And later:
var db = new DatabaseEntities(GetConnectionString());Or subclass you
ObjectContextclass and always use the new connection string:public class MyDatabaseEntities : DatabaseEntities { public MyDatabaseEntities() : base(GetConnectionString()) { } public static string GetConnectionString() { var conStr = System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseEntities"].ConnectionString; return conStr.Replace("%APPDATA%", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)); } }and use the new class anywhere.
更改您的连接字符串并使用
|DataDirectory|:<connectionStrings> <add name="DatabaseEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlServerCe.4.0;provider connection string="Data Source=|DataDirectory|\Database.sdf"" providerName="System.Data.EntityClient" /> </connectionStrings>(注意在
|DataDirectory|数据库文件路径中的使用。)然后
|DataDirectory|在应用程序的 Main 方法中提供值:AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));为您的 ObjectContext 类手动提供连接字符串。这样您就可以解析和更改连接字符串:
public static string GetConnectionString() { var conStr = System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseEntities"].ConnectionString; return conStr.Replace("%APPDATA%", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)); }然后:
var db = new DatabaseEntities(GetConnectionString());或子类化您的
ObjectContext类并始终使用新的连接字符串:public class MyDatabaseEntities : DatabaseEntities { public MyDatabaseEntities() : base(GetConnectionString()) { } public static string GetConnectionString() { var conStr = System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseEntities"].ConnectionString; return conStr.Replace("%APPDATA%", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)); } }并在任何地方使用新类。
回答by Karan Patel
I have another option. We don't need to replace anything. I am using below connection string without any replace and it's working fine.
我还有另一个选择。我们不需要更换任何东西。我使用下面的连接字符串没有任何替换,它工作正常。
<connectionStrings>
<add name="ProjectManagementDBEntities" connectionString="metadata=res://*/Models.ProjectManagementModels.csdl|res://*/Models.ProjectManagementModels.ssdl|res://*/Models.ProjectManagementModels.msl;provider=System.Data.SqlClient;provider connection string="data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\ProjectManagementDB.mdf;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"/>
</connectionStrings>
Main change is data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\ProjectManagementDB.mdf;integrated security=True;
主要变化是 data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\ProjectManagementDB.mdf;integrated security=True;
I hope this will save someone.
我希望这会救人。
回答by Rohit Vats
You have to replace the %APPDATA%in the code with the relative path -
你必须%APPDATA%用相对路径替换代码中的 -
var connectionString = ConfigurationManager.ConnectionStrings["DatabaseEntities"]
.ConnectionString;
connectionString.Replace("%APPDATA%",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

