2013-06-14 2 views
10

したがって、Entityフレームワークによって多数の移行が行われたアプリケーションがあります。 すべての移行のスクリプトを一度に取得したい場合は、-Scriptタグを使用するとうまく動作します。Entity Frameworkの移行に「GO」ステートメントを追加

しかし...それは私がスクリプト全体のためだけを周りに検索し、手動でこの問題にSql("GO");ヘルプを追加することなく、されている私たちにAlter view should be the first statement in a batch file...

ような問題を与えてSQLでGOステートメントを追加しません。パッケージコンソールマネージャを再び使用すると、例外が返されます。

System.Data.SqlClient.SqlException (0x80131904): Could not find stored procedure 'GO'. 

のみ-Scriptタグを使用するときに、これらのGOタグを追加する方法はありますか? そうでない場合は、これにはどのようなアプローチが適していますか?

注:複数のファイルを作成しようとしましたが、非常に多くの移行が行われているため、毎回維持することはほとんど不可能です。

答えて

10

新しいSqlServerMigrationSqlGenerator

を作成することができ、エンティティフレームワークの移行によって生成されたSQLを変更するために、我々は、移行の歴史の前と後にGOステートメントを追加するためにこれを行っています

public class MigrationScriptBuilder: SqlServerMigrationSqlGenerator 
{ 
    protected override void Generate(System.Data.Entity.Migrations.Model.InsertHistoryOperation insertHistoryOperation) 
    { 
     Statement("GO"); 

     base.Generate(insertHistoryOperation); 

     Statement("GO"); 

    } 
} 

その後、追加します

[...] 
internal sealed class Configuration : DbMigrationsConfiguration<PMA.Dal.PmaContext> 
{ 
    public Configuration() 
    { 
     SetSqlGenerator("System.Data.SqlClient", new MigrationScriptBuilder()); 
     AutomaticMigrationsEnabled = false; 
    } 
[...] 
Configurationコンストラクタで(あなたDbContextがあるプロジェクトの Migrationsフォルダに)それは、この新しいSQLジェネレータを使用するように、あなたは-scriptタグを使用してスクリプトを生成するとき、あなたは insert into [__MigrationHistory]はまた SqlServerMigrationSqlGeneratorの実装に使用すると、スクリプト生成のどの部分を無効にすることができ GO

に囲まれていることがわかります

はだから今、InsertHistoryOperationは適していました米国。あなたがSql('Alter View dbo.Foos As etc')を使用してビューを変更しようとしている場合は、あなたがEXECコマンド内でSQLを置くことによってGO文を追加することなく、should be the first statement in a batch fileエラーを回避することができます

+2

'-Script'タグを使用すると完全に動作します。私は 'SetSqlGenerator(" ..... '行をコメントアウトする必要がありますが、それ以外の場合は例外が再び発生するため、私は使用しません。しかし、これはただの行ではなく、 'Sql(" GO ");' everywhereを追加しました。ありがとう! – Tikkes

+0

InsertHistoryOperationが見つかりません。どのアセンブリですか? –

+3

ああ、EF 6のHistoryOperationに改名されたと思う。 –

13

Sql(EXEC('Alter View dbo.Foos As etc'))

+0

このことは、作成直後に表と列を塗りつぶすことを可能にする。すばらしいです! – blazkovicz

+0

WOW、それは本当にシンプルで機能します!それに感謝します! – trailmax

+0

ベストアンワース、ありがとう! – ArDumez

-2

だけで現在のステートメントを置き換えますa。置き換え( "GO"、 "");

8

Statement(sql, batchTerminator)のオプションの引数として、SqlServerMigrationSqlGeneratorに深い概念があります。ここにはSkypのアイデアに基づいたものがあります。これは、スクリプトモードでも動作しません。私たちのニーズは少し異なるので、GOはSkypとは異なる操作のためのものです。 Skypeの指示に従ってこのクラスをConfigurationに登録する必要があります。

public class MigrationScriptBuilder : SqlServerMigrationSqlGenerator 
    { 
     private string Marker = Guid.NewGuid().ToString(); //To cheat on the check null or empty of the base generator 

     protected override void Generate(AlterProcedureOperation alterProcedureOperation) 
     { 
      SqlGo(); 
      base.Generate(alterProcedureOperation); 
      SqlGo(); 
     } 
     protected override void Generate(CreateProcedureOperation createProcedureOperation) 
     { 
      SqlGo(); 
      base.Generate(createProcedureOperation); 
      SqlGo(); 
     } 
     protected override void Generate(SqlOperation sqlOperation) 
     { 
      SqlGo(); 
      base.Generate(sqlOperation); 
     } 

     private void SqlGo() 
     { 
      Statement(Marker, batchTerminator: "GO"); 
     } 

     public override IEnumerable<MigrationStatement> Generate(IEnumerable<MigrationOperation> migrationOperations, string providerManifestToken) 
     { 
      var result = new List<MigrationStatement>(); 
      var statements = base.Generate(migrationOperations, providerManifestToken); 

      bool pendingBatchTerminator = false; 
      foreach (var item in statements) 
      { 
       if(item.Sql == Marker && item.BatchTerminator == "GO") 
       { 
        pendingBatchTerminator = true; 
       } 
       else 
       { 
        if(pendingBatchTerminator) 
        { 
         item.BatchTerminator = "GO"; 
         pendingBatchTerminator = false; 
        } 
        result.Add(item); 
       } 
      } 

      return result; 
     } 
    } 
+1

これは私のために働いた!私はスクリプト引数の有無にかかわらず動作する方法を探していました。ありがとう! – ravinsp

+0

これは私のためにEF6がSqlResource経由で挿入されているストアドプロシージャ作成スクリプトの最後からgoステートメントを不可解に削除したときに機能しました。 EFの魔法は私が好きなものではありません。 – aaaaaa

関連する問題