使用WPF和 Entity Framework 时,我的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=&quot;Data Source=%APPDATA%\Folder\Database.sdf&quot;" 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%是只是没有被替换为实际的文件夹...

谢谢,

最佳答案

正如您已经认识到的那样,%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=&quot;Data Source=|DataDirectory|\Database.sdf&quot;" providerName="System.Data.EntityClient" />
    </connectionStrings>
    

    (注意在数据库文件的路径中使用|DataDirectory|。)

    然后在应用程序的Main方法中提供|DataDirectory|的值:
    AppDomain.CurrentDomain.SetData("DataDirectory",
        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
    

    请引用this MSDN page for more information
  • 手动提供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));
        }
    }
    

    并在任何地方使用新类。
  • 关于c# - 连接字符串中的%APPDATA%不能代替实际文件夹吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15037937/

    10-11 14:24