当使用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>
使用此代码时,它始终抛出以下错误:
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 ]
当我从命令提示符运行路径“%APPDATA%\ Folder \ Database.sdf”时它工作正常,如果我删除“%APPDATA%并硬编码路径它工作正常 - 所以它看起来像% APPDATA%只是没有替代实际的文件夹...
谢谢,
答案 0 :(得分:22)
正如您已经重新初始化的那样,%APPDATA%
或任何其他环境变量不会替换为连接字符串中各自的值。环境变量是与操作系统shell相关的东西。它们在命令提示符下工作,因为命令提示符显式解析输入的值并替换环境变量。这不是.NET Framwork通常执行的操作。
要实现此目的,您必须手动提供%APPDATA%
的值(使用Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
或Environment.GetEnvironmentVariable("APPDATA")
)。有两种选择:
更改连接字符串并使用|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|
。)
然后在应用程序的Main方法中提供|DataDirectory|
的值:
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));
}
}
并在任何地方使用新课程。
答案 1 :(得分:4)
我有另一种选择。我们不需要更换任何东西。我使用下面的连接字符串没有任何替换,它工作正常。
<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>
主要更改为data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\ProjectManagementDB.mdf;integrated security=True;
我希望这会拯救某人。
答案 2 :(得分:1)
您必须使用相对路径替换代码中的%APPDATA%
-
var connectionString = ConfigurationManager.ConnectionStrings["DatabaseEntities"]
.ConnectionString;
connectionString.Replace("%APPDATA%",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);