10

MyProject\App_Data\Cos.mdfでデータベースの場所を設定しようとしましたApp.config:

 <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\Cos.mdf;Initial Catalog=Cos;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
  </connectionStrings>

Program.cs私は書いた:

 static void Main(string[] args) {

        string relative = @"..\..\App_Data\Cos.mdf";
        string absolute = Path.GetFullPath(relative);

        AppDomain.CurrentDomain.SetData("DataDirectory", absolute); 
        Console.WriteLine(absolute);
        Console.ReadKey();
 }

表示されたパスは次のとおりです(間違えていないことを示すために貼り付けました):

ここに画像の説明を入力

しかし、パッケージ マネージャー コンソールを true にenable-migrations変更すると、次のように入力するとエラーが発生します。AutomaticMigrationsupdate-database

Cannot attach the file 'C:\Users\s8359_000\Documents\Visual Studio 2013\Projects\Projekt5 — kopia\Projekt5\bin\Debug\Cos.mdf' as database 'Cos'.

Debug.NET がディレクトリにデータベースを作成しようとするのはなぜですか?! 私はこのトピックについて StackOverflow で 15 のテーマを調べましたが、誰もがうまくいかない回答を複製しているようです。

SRUTZKYの回答後に編集 はい、そうです、エラーがあります。あなたの答えの後にいくつかの組み合わせを試しましたが、残念ながらどれもうまくいきませんでした。

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\baza.mdf;Initial Catalog=baza;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
  </connectionStrings>

そしてメイン

  static void Main(string[] args) {

        Console.WriteLine("BEFORE:" + AppDomain.CurrentDomain.GetData("DataDirectory"));
        string relative = @"..\..\App_Data\Cos.mdf";
        string absolute = Path.GetFullPath(relative);
        absolute = Path.GetDirectoryName(@absolute);
        AppDomain.CurrentDomain.SetData("DataDirectory", @absolute);
        Console.WriteLine(@absolute);
        Console.WriteLine(AppDomain.CurrentDomain.GetData("DataDirectory"));
        Console.ReadKey();
}

次に、コンソールに入ります:

ここに画像の説明を入力

Migrationsディレクトリとを削除した後enable-migrations、自動移行をtrueにすると、次のupdate-databaseようになります。

PM> update-database '-Verbose' フラグを指定して、ターゲット データベースに適用されている SQL ステートメントを表示します。System.Data.SqlClient.SqlException (0x80131904): ファイルのアクティブ化エラーが発生しました。物理ファイル名「\baza.mdf」が間違っている可能性があります。追加のエラーを診断して修正し、操作を再試行してください。データベースの作成に失敗しました。リストされたいくつかのファイル名を作成できませんでした。関連するエラーを確認してください。System.Data.SqlClient.SqlConnection.OnError で (SqlException 例外、ブール値の breakConnection、アクション1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) で System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds (String methodName、Boolean async、Int32 timeout、Boolean asyncWrite) での dataReady) System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery (TaskCompletionSource 1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext1 c) での System.Data.Entity.Infrastructure.Interception .InternalDispatcher 1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func3 オペレーション、TInterceptionContext インターセプションコンテキスト、アクション3 executing, Action3 実行) System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand コマンド、DbCommandInterceptionContextinterceptionContext) で System.Data.Entity.SqlServer.SqlProviderServices.<>c__DisplayClass1a.b__19(DbConnection conn) で System.Data.Entity .SqlServer.SqlProviderServices.<>c__DisplayClass33.b__32() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.b__0() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func 1 operation) at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation) at System.Data.Entity.SqlServer.SqlProviderServices.UsingConnection(DbConnection sqlConnection, Action1 act) System.Data.Entity.SqlServer.SqlProviderServices.UsingMasterConnection で (DbConnection sqlConnection、アクション1 act) at System.Data.Entity.SqlServer.SqlProviderServices.CreateDatabaseFromScript(Nullable1 commandTimeout、DbConnection sqlConnection、文字列 createDatabaseScript) System.Data.Entity.SqlServer.SqlProviderServices.DbCreateDatabase (DbConnection 接続、Nullable) で1 commandTimeout, StoreItemCollection storeItemCollection) at System.Data.Entity.Core.Common.DbProviderServices.CreateDatabase(DbConnection connection, NullableSystem.Data.Entity.Migrations.Utilities.DatabaseCreator.Create(DbConnection 接続) で System.Data.Entity.Core.Objects.ObjectContext.CreateDatabase() で 1 commandTimeout、StoreItemCollection (storeItemCollection)、System.Data.Entity.Migrations.DbMigrator で.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) at System.Data.Entity.Migrations.Infrastructure .MigratorBase.Update(String targetMigration) で System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run() で System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) で System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
System.Data.Entity.Migrations.Design.ToolingFacade.Run (BaseRunner ランナー) で System.Data.Entity.Migrations.Design.ToolingFacade.Update (文字列 targetMigration、ブール値の力) で System.Data.Entity.Migrations.UpdateDatabaseCommand で。 <>c__DisplayClass2.<.ctor>b__0() at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(アクション コマンド) ClientConnectionId:23ca49c1-4797-4bc3-8f16-f34fd77f2cbe ファイルのアクティブ化エラーが発生しました。物理ファイル名「\baza.mdf」が間違っている可能性があります。追加のエラーを診断して修正し、操作を再試行してください。データベースの作成に失敗しました。リストされたいくつかのファイル名を作成できませんでした。関連するエラーを確認してください。午後>

4

3 に答える 3

10

Enable-Migrations コマンドで作成された Configuration クラスで、Update-Database の DataDirectory を設定できます。

internal sealed class Configuration : DbMigrationsConfiguration<DataContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        var dataDirPath = "<YourPath>";
        AppDomain.CurrentDomain.SetData("DataDirectory", dataDirPath);
    }
}
于 2015-08-09T18:51:12.040 に答える
8

問題 1 (/2)

の値を設定するときDataDirectoryは、ファイルではなくディレクトリである必要があります。absolute次の変数の値を渡しています。

C:\Users\s8359_000\Documents\Visual Studio 2013\Projects\Projekt5 — kopia\Projekt5\App_Data\Cos.mdf

ファイル名が含まれています。それは有効ではありません。DataDirectoryは置換値であるため、次のように指定します。

AttachDbFilename=|DataDirectory|\Cos.mdf

接続文字列では、次のように変換されます。

C:\Users\s8359_000\Documents\Visual Studio 2013\Projects\Projekt5 — kopia\Projekt5\App_Data\Cos.mdf\Cos.mdf

これは有効なパスではありません。そのため、.NET は の値がDataDirectory無効であることを認識し、それを使用しないため、現在の作業ディレクトリで開始するようです。

の値を設定するPath.GetDirectoryName(relative)代わりに使用すると、の値が次のように設定されるため、機能するはずです。Path.GetFullPath(relative)absoluteDataDirectory

C:\Users\s8359_000\Documents\Visual Studio 2013\Projects\Projekt5 — kopia\Projekt5\App_Data

接続文字列の MSDN ページには、「|DataDirectory| 置換文字列のサポート...」というタイトルのセクションの下の方にいくつかの追加の詳細があります。

問題 2 (/2)

  1. AppDomainには「DataDirectory」が設定されています。
  2. コンソール アプリには、開始時に作成され、終了時に消える独自の AppDomains があります。
  3. パッケージ マネージャー (実行している場所Update-Database) は、「DataDirectory」の値を設定しているコンソール アプリの AppDomain にアクセスできません。
  4. 次のいずれかを行う必要があります。
    1. Package Manager で "DataDirectory" をプログラムで設定する、または
    2. コンソール アプリのコンテキスト内で "update-database" をプログラムで実行する

プログラムで Package Manager とやり取りする方法はわかりませんが、「データベースの更新」プロセスをプログラムで起動する方法はわかりました。「DataDirectory」の値を設定した直後に次の行を追加するだけです。

Database.SetInitializer(new
    MigrateDatabaseToLatestVersion<YourDataContextName, Configuration>()
 );

また、2 つとは言わないまでも、少なくとも 1 つのusingステートメントが必要です。

  • using System.Data.Entity;
  • using ProjectName.Migrations; // namespace of Migrations\Configuration.cs

これだけではデータベースが作成されないことに注意してください。保留中の変更は、DbContext を介してデータベースに最初にアクセスしたときに発行されます。

例:

using System.Data.Entity;
using Projekt5.Migrations;

....

string relative = @"..\..\App_Data\Cos.mdf";
string absolute = Path.GetDirectoryName(absolute);
AppDomain.CurrentDomain.SetData("DataDirectory", absolute);
Database.SetInitializer(new
    MigrateDatabaseToLatestVersion<Projekt5Context, Configuration>()
 );
// database not created yet

using (var db = new Projekt5Context())
{
  db.Things.Add(new Thing { Name = "OMG This works!" });
  db.SaveChanges();
} 
// database CREATED!

また、Package Manager を介して次の呼び出しを 1 回行う必要がある場合あります (データベースに対してすぐに何もしないため、接続文字列にはアクセスしません)。

Add-Migration InitialMigration

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

呼び出すコード行が でSetInitializerあるとMigrateDatabaseToLatestVersion、実行されるたびに (これがコンソール アプリの最初に行われる理由です)、「モデル」にあるものの間で変更が同期されます (つまり、アセンブリにコンパイルされるようになりました) とデータベースに接続し、データベースが最新バージョンであることを確認します。これは、新しいテーブルがDbContextクラスで表現されていることを前提としています。ただし、追加の Package Manager コマンドを実行する必要はありません。

于 2015-01-04T02:54:10.973 に答える