2017-09-21 3 views
1

Entity Frameworkを使用して作成されたそれぞれの新しいテーブルの後に、SQLスクリプトを実行します。SqlServerMigrationSqlGeneratorでSQLコードを個別に実行する方法を生成しますか?

私はこのような「CreateTableOperation」のオーバーライドを作成しました:

protected override void Generate(CreateTableOperation createTableOperation) 
{ 
    string tenantID = "tenantID"; 
    base.Generate(createTableOperation); 
    //If the table contain the column "tenantID", 
    if ((from x in createTableOperation.Columns 
     where x.Name == tenantID 
     select x).Any() 
    ) 
    { 
     //Add the Security Policies for this table 
     using (var writer = Writer()) 
     { 
      writer.WriteLine("ALTER SECURITY POLICY rls.tenantAccessPolicy "); 
      //Note: dbo. is already part of the .Name, don't add it manually before .Name 
      writer.WriteLine($"ADD FILTER PREDICATE rls.fn_tenantAccessPredicateWithSuperUser([{tenantID}]) ON [{createTableOperation.Name}], "); 
      writer.WriteLine($"ADD BLOCK PREDICATE rls.fn_tenantAccessPredicateWithSuperUser([{tenantID}]) ON [{createTableOperation.Name}] "); 
      Statement(writer); 
     } 
    } 
} 

のは、私は新しいクラスのTEST 'を作成しましょう。 問題は、Update-Databaseをパッケージマネージャコンソールで実行したときに、SQLが1つの大きなブロックで実行され、テーブルがまだ作成されていないためにエラーが発生し、table.nameを取得しようとしています。アップデート・データベース後のパッケージマネージャの結果:それは存在しないか、またはあなたが権限を持っていないので、

CREATE TABLE [dbo].[TEST] (
    [ID] [int] NOT NULL IDENTITY, 
    [NameTEST] [nvarchar](max), 
    [TenantID] [int] NOT NULL, 
    CONSTRAINT [PK_dbo.TEST] PRIMARY KEY ([ID]) 
) 
ALTER SECURITY POLICY rls.tenantAccessPolicy 
ADD FILTER PREDICATE rls.fn_tenantAccessPredicateWithSuperUser([tenantID]) ON [dbo.TEST], 
ADD BLOCK PREDICATE rls.fn_tenantAccessPredicateWithSuperUser([tenantID]) ON [dbo.TEST] 

は、オブジェクト「dbo.TEST」を見つけることができません。 の間を分割する方法はありますか?生成(createTableOperation);と私のステートメント(ライター);? (私はすでに多くの成功をせずに 'GO'で複数のことを試しました)。それとも、私はそのメソッドにコードを入れることになっていないのですか?

答えて

0

私が代わりにやったGenerate(CreateTableOperation createTableOperation)方法で、動的SQLスクリプトを生成

  • に何だったGenerate(CreateTableOperation createTableOperation).

    にコード/バッチSQLを分離するためのソリューション/ドキュメントを見つけることができませんでした

    /// <summary> 
        /// Generate dynamically named .sql file for CREATE and DROP Security Policies (Row-Level Security (Company can't see/insert data of another company)) 
        /// </summary> 
        /// <param name="createTableOperation">Default parameter that comes with the override method.</param> 
        protected override void Generate(CreateTableOperation createTableOperation) 
        { 
         base.Generate(createTableOperation); 
        string fullFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\Migrations\\SQLscripts\\SecurityPolicies"); 
    
        //Remove the schema for the dynamic creation of the .sql filename else it throw an exception: 
        int indexOfDot = createTableOperation.Name.IndexOf("."); 
        indexOfDot++; //Because it's 0 base, add 1 char 
        string tableNameWithoutSchema = (indexOfDot < 0) ? createTableOperation.Name : createTableOperation.Name.Remove(0, indexOfDot); 
    
        string filePathCreate = Path.Combine(fullFolderPath, $"CreateSecurityPolicies_{tableNameWithoutSchema}.sql"); 
        string filePathDrop = Path.Combine(fullFolderPath, $"DropSecurityPolicies_{tableNameWithoutSchema}.sql"); 
    
        //If .sql files doesn't exists, create them 
        if (!File.Exists(filePathCreate)) 
        { 
         using (StreamWriter sw = new StreamWriter(filePathCreate, true)) 
         { 
          sw.WriteLine("ALTER SECURITY POLICY rls.tenantAccessPolicy"); 
          //Note: Don't concatenate 'dbo.{}' because 'createTableOperation.Name' already include 'dbo' 
          sw.WriteLine($" ADD FILTER PREDICATE rls.fn_tenantAccessPredicateWithSuperUser(CompanyID) ON {createTableOperation.Name},"); 
          sw.WriteLine($" ADD BLOCK PREDICATE rls.fn_tenantAccessPredicateWithSuperUser(CompanyID) ON {createTableOperation.Name}"); 
          sw.WriteLine("GO"); 
          sw.Close(); 
         } 
        } 
    
        if (!File.Exists(filePathDrop)) 
        { 
         using (StreamWriter sw = new StreamWriter(filePathDrop, true)) 
         { 
          sw.WriteLine("ALTER SECURITY POLICY rls.tenantAccessPolicy"); 
          sw.WriteLine($" DROP FILTER PREDICATE ON {createTableOperation.Name},"); 
          sw.WriteLine($" DROP BLOCK PREDICATE ON {createTableOperation.Name}"); 
          sw.WriteLine("GO"); 
          sw.Close(); 
         } 
        } 
    
    
    } 
    
  • 次に、フォルダ内のSQLスクリプトを使用して、手動で自分のソリューションに追加します。

  • 空の(最新の)移行クラスにコードを追加するだけで、SQLスクリプトを実行することができます。

    public override void Up() 
    { 
        string sqlFilePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\Migrations\\SQLscripts\\CreateSecurityPolicies_Client.sql"); 
        string sqlText = System.IO.File.ReadAllText(sqlFilePath); 
        Sql(sqlText); 
    } 
    
    public override void Down() 
    { 
        string sqlFilePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\Migrations\\SQLscripts\\DropSecurityPolicies_Client.sql"); 
        string sqlText = System.IO.File.ReadAllText(sqlFilePath); 
        Sql(sqlText); 
    } 
    

これは、私は一瞬を考え出すことができる最善の方法です。他のEntityFrameworkプログラマーに役立つことを願っています!

関連する問題