10

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=&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% のように見えます。実際のフォルダに置き換えられていないだけです...

ありがとう、

4

3 に答える 3

26

既にお気づきのように、%APPDATA%または他の環境変数は、接続文字列のそれぞれの値に置き換えられません。環境変数は、オペレーティング システムのシェルに関連するものです。コマンドプロンプトは入力された値を明示的に解析し、環境変数を置き換えるため、コマンドプロンプトで機能します。これは、.NET Framwork が通常実行するものではありません。

これを実現するには、%APPDATA%(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)またはを使用してEnvironment.GetEnvironmentVariable("APPDATA")) の値を手動で指定する必要があります。次の 2 つのオプションがあります。

  1. 接続文字列を変更して使用します|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|(データベース ファイルへのパスでの使用に注意してください。)

    次に|DataDirectory|、アプリケーションの Main メソッドで値を指定します。

    AppDomain.CurrentDomain.SetData("DataDirectory",
        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
    

    詳細については、この MSDN ページを参照してください

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

    新しいクラスをどこでも使用できます。

于 2013-02-23T07:07:02.290 に答える