복붙노트

[SQL] 엔티티 프레임 워크 마이그레이션에 'GO'문을 추가

SQL

엔티티 프레임 워크 마이그레이션에 'GO'문을 추가

내가 엔티티 프레임 워크에 의해 마이그레이션의 톤과 응용 프로그램이 그래서. 우리는 한 번 잘 동작을 -Script 태그를 않는 사용에 모든 마이그레이션에 대한 스크립트를 싶어.

그러나 ...이 배치 파일의 첫 번째 문이어야한다 우리에게 뷰 변경 같은 문제를주는 SQL에서 GO 문을 추가하지 않습니다 ...

나는 주변 검색 및 SQL 수동 ( "GO")을 추가 한; 이 문제에 있지만 전체 스크립트에 대한 도움말을 표시합니다. 내가 다시 패키지 콘솔 관리자를 사용하는 경우는 예외를 반환합니다.

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

-Script 태그를 사용하는 경우에만이 GO 태그를 추가하는 방법이 있나요? 되지 않은 경우,이에 대한 좋은 방법은 무엇인가?

참고 : 우리는 또한 여러 파일을 가지고 시도했지만 우리는 많은 마이그레이션을 갖고 있기 때문에,이 모든 시간을 유지하기 위해 근처 불가능하다.

해결법

  1. ==============================

    1.엔티티 프레임 워크 마이그레이션에 의해 생성 된 SQL을 변경하려면 새 SqlServerMigrationSqlGenerator를 만들 수 있습니다

    엔티티 프레임 워크 마이그레이션에 의해 생성 된 SQL을 변경하려면 새 SqlServerMigrationSqlGenerator를 만들 수 있습니다

    우리는 이전과 이주의 역사 후 GO 문을 추가하기 위해 이런 짓을했는지 :

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

    다음은이 새로운 SQL 생성기를 사용 그래서 (당신 DbContext이 프로젝트의 마이그레이션 폴더에) 구성 생성자에 추가 :

    [...]
    internal sealed class Configuration : DbMigrationsConfiguration<PMA.Dal.PmaContext>
    {
        public Configuration()
        {
            SetSqlGenerator("System.Data.SqlClient", new MigrationScriptBuilder());
            AutomaticMigrationsEnabled = false;
        }
    [...]
    

    당신이 -Script 태그를 사용하여 스크립트를 생성 할 때 그래서 지금, 당신은 [__MigrationHistory]에 삽입이 GO에 둘러싸여 있음을 알 수

    또한 SqlServerMigrationSqlGenerator의 구현에 스크립트 생성의 일부를 대체 할 수는 InsertHistoryOperation 우리 적합했다.

  2. ==============================

    2.당신은 SQL을 사용하여보기를 변경하려는 경우 ( "알터보기 dbo.Foos로 등"), 당신은 EXEC 명령 내부의 SQL을 넣어 GO 문을 추가하지 않고 배치 파일 오류에서 첫 번째 문이어야한다 피할 수 있습니다 :

    당신은 SQL을 사용하여보기를 변경하려는 경우 ( "알터보기 dbo.Foos로 등"), 당신은 EXEC 명령 내부의 SQL을 넣어 GO 문을 추가하지 않고 배치 파일 오류에서 첫 번째 문이어야한다 피할 수 있습니다 :

    SQL ( "EXEC ( '알터보기 dbo.Foos로 등')")

  3. ==============================

    3.문에 대한 선택적 인수 (SQL, batchTerminator)로 SqlServerMigrationSqlGenerator 깊은 개념의 존재를 돌립니다. 여기 Skyp의 아이디어를 기반으로 뭔가입니다. 그것은 -script 모드 또는 둘 다 작동합니다. 숙련 된 GO는 우리의 요구는 약간의 차이가 때문 Skyp에 대한 다른 작업을위한 것입니다. 그런 다음 Skyp 지침에 따라 구성에서이 클래스를 등록해야합니다.

    문에 대한 선택적 인수 (SQL, batchTerminator)로 SqlServerMigrationSqlGenerator 깊은 개념의 존재를 돌립니다. 여기 Skyp의 아이디어를 기반으로 뭔가입니다. 그것은 -script 모드 또는 둘 다 작동합니다. 숙련 된 GO는 우리의 요구는 약간의 차이가 때문 Skyp에 대한 다른 작업을위한 것입니다. 그런 다음 Skyp 지침에 따라 구성에서이 클래스를 등록해야합니다.

        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;
            }
        }
    
  4. ==============================

    4.가장 쉬운 방법은 / ** / 이동 문 앞에 추가하는 것입니다.

    가장 쉬운 방법은 / ** / 이동 문 앞에 추가하는 것입니다.

  5. ==============================

    5.그냥 .Replace ( "GO", "")와 현재의 문을 대체;

    그냥 .Replace ( "GO", "")와 현재의 문을 대체;

  6. from https://stackoverflow.com/questions/17105716/adding-go-statements-to-entity-framework-migrations by cc-by-sa and MIT license