バックグラウンド:
長期間の開発で作成された複数の (読み取り ~ 60) 移行を含むef-migrationsを使用するプロジェクトがあります。当然のことながら、これらの移行には次のものも含まれます。
走るとすべてがユニコーンと虹
Update-Database
各移行は個別のバッチとして実行されるためです。ただし、SQL Scripts
これらの移行用に作成する場合は、
Update-Database -Script
以下に説明するように、いくつかの問題が発生しました。
問題 1:
複数の移行ファイルにわたって複数の制約を削除する場合、EF によって生成されたスクリプトは、削除に使用する変数を再宣言する傾向があります。これは、同じ移行ファイル内の変数名の一意性が保証されるためですが、ファイルが変更されると、カウンターがリセットされ、名前が重複するためです。
問題 2:
CREATE TRIGGER
SQL は、それが常にバッチ内の最初のステートメントであることを強制します。スクリプトが生成されると、EF は の内容をSql("CREATE TRIGGER ... ");
認識しないため、特別に処理しません。したがって、ステートメントがスクリプト ファイルの途中に表示され、エラーが発生する場合があります。
解決策: (または、そう考えた!)
2 つの問題に対する一般的/常識的な解決策は、SQL バッチの Begin/End を適切な場所に挿入することです。手動でこれを行うと、私は非常に金持ちになるので、効率的な解決策ではありません.
代わりに、@DavidSette が提供する手法を使用しました。効果的にオーバーライドする新しいBatchSqlServerMigrationSqlGenerator
継承を作成し、機密性の高いステートメントを次のように強制します。SqlServerMigrationSqlGenerator
dropColumnOperation
sqlOperation
GO
protected override void Generate (System.Data.Entity.Migrations.Model.DropColumnOperation dropColumnOperation)
{
base.Generate(dropColumnOperation);
Statement("GO");
}
ブーブー:
このソリューションは、次のエラーでフラグUpdate-Database
なしで実行を中断します。-Script
System.Data.SqlClient.SqlException (0x80131904): Could not find stored procedure 'GO'.
これは、カスタム ジェネレーターによって追加されました。理由は定かではありませんが、EF が認識しないのにはかなりの理由があるはずGO
です。
より詳しい情報:
- 移行: 2 つの制約を削除するスクリプトで @var0 変数を複製する
- 変数名 '@number' は既に宣言されています
- MigratorScriptingDecorator によって生成された SQL スクリプトをオーバーライドするにはどうすればよいですか
- Entity Framework の移行: -Script 出力のみに Go ステートメントを含める
完全なエラー:
Applying code-based migration: 201205181406363_AddTriggerForOverlap.
GO
System.Data.SqlClient.SqlException (0x80131904): Could not find stored procedure 'GO'.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout)
at 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.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, Boolean downgrading, Boolean auto)
at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore()
at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
ClientConnectionId:ac53af4b-1f9b-4849-a0da-9eb33b836caf
Could not find stored procedure 'GO'.
したがって、基本的にスクリプトを修正すると、重要なコマンドが壊れます。2つの悪のどちらが小さいかを判断するのを手伝ってください!