配置コントリビューターを作成して、データベース プロジェクトの配置時にカスタム動作を実行できます。 DeploymentPlanModifier または DeploymentPlanExecutor を作成できます。 計画の実行前に計画を変更する場合は DeploymentPlanModifier を使用し、計画の実行中に操作を実行する場合は DeploymentPlanExecutor を使用します。 このチュートリアルでは、DeploymentUpdateReportContributor という名前の DeploymentPlanExecutor を作成して、データベース プロジェクトの配置時に実行されたアクションについてのレポートを生成します。 このビルド コントリビューターはレポートを生成するかどうかを制御するパラメーターを受け付けるため、必要な追加ステップを実行する必要があります。
このチュートリアルでは、次の主要タスクを行います。
DeploymentPlanExecutor 型の配置コントリビューターの作成
配置コントリビューターのインストール
配置コントリビューターのテスト
必須コンポーネント
このチュートリアルを実行するには、次のコンポーネントが必要です。
Visual Studio 2010 Premium または Visual Studio 2010 Ultimate がコンピューターにインストールされていること
データベース オブジェクトを含むデータベース プロジェクト
データベース プロジェクトを配置できる SQL Server のインスタンス
注意
このチュートリアルは、既に Visual Studio のデータベース機能を使い慣れているユーザーを対象としています。 また、クラス ライブラリの作成方法、コード エディターを使用してクラスにコードを追加する方法など、Visual Studio の基本的な概念を理解している必要があります。
配置コントリビューターの作成
配置コントリビューターを作成するには、次のタスクを実行する必要があります。
クラス ライブラリ プロジェクトの作成および必要な参照の追加
DeploymentPlanExecutor から継承した DeploymentUpdateReportContributor という名前のクラスの定義
OnPopulateArguments メソッドおよび OnExecute メソッドのオーバーライド
プライベート ヘルパー クラスの追加
結果として得られるアセンブリのビルド
クラス ライブラリ プロジェクトを作成するには
MyDeploymentContributor という名前の Visual Basic または Visual C# のクラス ライブラリ プロジェクトを作成します。
ソリューション エクスプローラーで、[参照] フォルダーを右クリックし、[参照の追加] をクリックします。
[.NET] タブをクリックします。
[Microsoft.Data.Schema] エントリおよび [Microsoft.Data.Schema.Sql] エントリを強調表示し、[OK] をクリックします。
次に、コードをクラスに追加します。
DeploymentUpdateReportContributor クラスを定義するには
コード エディターで、次の using ステートメントまたは Imports ステートメントに一致するように、class1.cs ファイルを変更します。
using System; using System.Collections.Generic; using System.Text; using Microsoft.Data.Schema.Build; using Microsoft.Data.Schema.Extensibility; using Microsoft.Data.Schema.Sql; using System.IO; using Microsoft.Data.Schema.SchemaModel; using System.Xml; using Microsoft.Data.Schema; using Microsoft.Data.Schema.Sql.Build;
Imports System Imports System.Collections.Generic Imports System.Text Imports Microsoft.Data.Schema.Build Imports Microsoft.Data.Schema.Extensibility Imports Microsoft.Data.Schema.Sql Imports System.IO Imports Microsoft.Data.Schema.SchemaModel Imports System.Xml Imports Microsoft.Data.Schema Imports Microsoft.Data.Schema.Sql.Build
クラス定義を次のように更新します。
[DatabaseSchemaProviderCompatibility(typeof(SqlDatabaseSchemaProvider))] class DeploymentUpdateReportContributor : DeploymentPlanExecutor { }
''' <summary> ''' The DeploymentUpdateReportContributor class demonstrates ''' how you can create a class that inherits DeploymentPlanExecutor ''' to perform actions when you execute the deployment plan ''' for a database project. ''' </summary> <DatabaseSchemaProviderCompatibility(GetType(SqlDatabaseSchemaProvider))> Public Class DeploymentUpdateReportContributor Inherits DeploymentPlanExecutor End Class
これで、ビルド コントリビューターの定義が完了しました。属性を使用して、このコントリビューターが、SqlDatabaseSchemaProvider から継承する任意のデータベース スキーマ プロバイダーと互換性があることを指定しました。
次に、以下のメンバーを追加します。このメンバーを使用して、現在のプロバイダーがコマンド ライン パラメーターを受け入れることができるようにします。
private const string GenerateUpdateReport = "GenerateUpdateReport";
Dim GenerateUpdateReport As String = "GenerateUpdateReport"
このメンバーにより、ユーザーはレポートを生成するかどうかを GenerateUpdateReport オプションで指定できるようになります。
次に、OnPopulateArguments メソッドをオーバーライドして、配置コントリビューターに渡す引数のリストを作成します。
OnPopulateArguments をオーバーライドするには
DeploymentUpdateReportContributor クラスに次のオーバーライド メソッドを追加します。
/// <summary> /// Override the OnPopulateArgument method to build a list of arguments from the input /// configuration information. /// </summary> protected override IList<ContributorArgumentConfiguration> OnPopulateArguments() { List<ContributorArgumentConfiguration> args = new List<ContributorArgumentConfiguration>(); // Generate reports when in debug configuration args.Add(new ContributorArgumentConfiguration( GenerateUpdateReport, "true", "'$(Configuration)' == 'Debug'")); return args; }
''' <summary> ''' Override the OnPopulateArgument method to build a list of arguments from the input ''' configuration information. ''' </summary> Protected Overloads Overrides Function OnPopulateArguments() As IList(Of ContributorArgumentConfiguration) Dim args As New List(Of ContributorArgumentConfiguration)() ' Generate reports when in debug configuration args.Add(New ContributorArgumentConfiguration(GenerateUpdateReport, "true", "'$(Configuration)' == 'Debug'")) Return args End Function
ContributorArgumentConfiguration オブジェクトを構築し、引数リストに追加します。 既定では、デバッグ ビルドの生成時にレポートが生成されます。
次に、OnExecute メソッドをオーバーライドして、データベース プロジェクトの配置時に実行するコードを追加します。
OnExecute をオーバーライドするには
次のメソッドを DeploymentUpdateReportContributor クラスに追加します。
/// <summary> /// Override the OnExecute method to perform actions when you execute the deployment plan for /// a database project. /// </summary> protected override void OnExecute(DeploymentPlanContributorContext context) { // determine whether the user specified a report is to be generated bool generateReport = false; string generateReportValue; if (context.Arguments.TryGetValue(GenerateUpdateReport, out generateReportValue) == false) { // couldn't find the GenerateUpdateReport argument, so do not generate generateReport = false; } else { // GenerateUpdateReport argument was specified, try to parse the value if (bool.TryParse(generateReportValue, out generateReport)) { // if we end up here, the value for the argument was not valid. // default is false, so do nothing. } } if (generateReport == false) { // if user does not want to generate a report, we are done return; } // We will output to the same directory where the deployment script // is output or to the current directory string reportPrefix = context.Options.TargetDatabaseName; string reportPath; if (string.IsNullOrEmpty(context.DeploymentScriptPath)) { reportPath = Environment.CurrentDirectory; } else { reportPath = Path.GetDirectoryName(context.DeploymentScriptPath); } FileInfo summaryReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".summary.xml")); FileInfo detailsReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".details.xml")); // Generate the reports by using the helper class DeploymentReportWriter DeploymentReportWriter writer = new DeploymentReportWriter(context); writer.WriteReport(summaryReportFile); writer.IncludeScripts = true; writer.WriteReport(detailsReportFile); string msg = "Deployment reports ->" + Environment.NewLine + summaryReportFile.FullName + Environment.NewLine + detailsReportFile.FullName; DataSchemaError reportMsg = new DataSchemaError(msg, ErrorSeverity.Message); base.PublishMessage(reportMsg); }
''' <summary> ''' Override the OnExecute method to perform actions when you execute the deployment plan for ''' a database project. ''' </summary> Protected Overloads Overrides Sub OnExecute(ByVal context As DeploymentPlanContributorContext) ' output the names and values for any provided arguments For Each arg As KeyValuePair(Of String, String) In context.Arguments Dim argMsg As New DataSchemaError((arg.Key & "=") + arg.Value, ErrorSeverity.Message) Me.PublishMessage(argMsg) Next ' determine whether the user specified a report is to be generated Dim generateReport As Boolean = False Dim generateReportValue As String If context.Arguments.TryGetValue(GenerateUpdateReport, generateReportValue) = False Then ' couldn't find the GenerateUpdateReport argument, so do not generate generateReport = False Else ' GenerateUpdateReport argument was specified, try to parse the value If Boolean.TryParse(generateReportValue, generateReport) Then ' if we end up here, the value for the argument was not valid. ' default is false, so do nothing. End If End If If generateReport = False Then ' if user does not want to generate a report, we are done Exit Sub End If ' We will output to the same directory where the deployment script ' is output or to the current directory Dim reportPrefix As String = context.Options.TargetDatabaseName Dim reportPath As String If String.IsNullOrEmpty(context.DeploymentScriptPath) Then reportPath = Environment.CurrentDirectory Else reportPath = Path.GetDirectoryName(context.DeploymentScriptPath) End If Dim summaryReportFile As New FileInfo(Path.Combine(reportPath, reportPrefix & ".summary.xml")) Dim detailsReportFile As New FileInfo(Path.Combine(reportPath, reportPrefix & ".details.xml")) ' Generate the reports by using the helper class DeploymentReportWriter Dim writer As New DeploymentReportWriter(context) writer.WriteReport(summaryReportFile) writer.IncludeScripts = True writer.WriteReport(detailsReportFile) Dim msg As String = ("Deployment reports ->" & Environment.NewLine) + summaryReportFile.FullName + Environment.NewLine + detailsReportFile.FullName Dim reportMsg As New DataSchemaError(msg, ErrorSeverity.Message) MyBase.PublishMessage(reportMsg) End Sub
この OnExecute メソッドに DeploymentPlanContributorContext オブジェクトが渡され、指定されたすべての引数、ソースおよびターゲットのデータベース モデル、ビルド プロパティ、および拡張ファイルにアクセスできるようになります。 この例では、モデルを取得し、このモデルについての情報を出力するヘルパー関数を呼び出します。 このメソッドには、発生したエラーを報告するために使用する ErrorManager も渡されます。
重要な型およびメソッドは、DataSchemaModel、ModelStore、ModelComparisonResult、DatabaseSchemaProvider、DeploymentPlanHandle、および SchemaDeploymentOptions です。
次に、配置計画の詳細を調べるヘルパー クラスを定義します。
レポート本文を生成するヘルパー クラスを追加するには
最初に、次のコードを追加して、ヘルパー クラスとそのメソッドのスケルトンを追加します。
/// <summary> /// This class is used to generate a deployment /// report. /// </summary> private class DeploymentReportWriter { /// <summary> /// The constructor accepts the same context info /// that was passed to the OnExecute method of the /// deployment contributor. /// </summary> public DeploymentReportWriter(DeploymentPlanContributorContext context) { } /// <summary> /// Property indicating whether script bodies /// should be included in the report. /// </summary> public bool IncludeScripts { get; set; } /// <summary> /// Drives the report generation, opening files, /// writing the beginning and ending report elements, /// and calling helper methods to report on the /// plan operations. /// </summary> internal void WriteReport(FileInfo reportFile) { } /// <summary> /// Writes details for the various operation types /// that could be contained in the deployment plan. /// Optionally writes script bodies, depending on /// the value of the IncludeScripts property. /// </summary> private void ReportPlanOperations(XmlWriter xmlw) { } /// <summary> /// Returns the category of the specified element /// in the source model /// </summary> private string GetElementCategory(IModelElement element) { } /// <summary> /// Returns the name of the specified element /// in the source model /// </summary> private string GetElementName(IModelElement element) { } }
''' <summary> ''' This class is used to generate a deployment ''' report. ''' </summary> Private Class DeploymentReportWriter Public Sub New(ByVal context As DeploymentPlanContributorContext) End Sub Private _includeScripts As Boolean ''' <summary> ''' Property indicating whether script bodies ''' should be included in the report. ''' </summary> Public Property IncludeScripts() As Boolean Get IncludeScripts = _includeScripts End Get Set(ByVal value As Boolean) _includeScripts = value End Set End Property ''' <summary> ''' Drives the report generation, opening files, ''' writing the beginning and ending report elements, ''' and calling helper methods to report on the ''' plan operations. ''' </summary> Friend Sub WriteReport(ByVal reportFile As FileInfo) End Sub ''' <summary> ''' Writes details for the various operation types ''' that could be contained in the deployment plan. ''' Optionally writes script bodies, depending on ''' the value of the IncludeScripts property. ''' </summary> Private Sub ReportPlanOperations(ByVal xmlw As XmlWriter) End Sub ''' <summary> ''' Returns the category of the specified element ''' in the source model ''' </summary> Private Function GetElementCategory(ByVal element As IModelElement) As String Return "" End Function ''' <summary> ''' Returns the name of the specified element ''' in the source model ''' </summary> Private Function GetElementName(ByVal element As IModelElement) As String Return "" End Function End Class
変更内容を Class1.cs に保存します。
次に、クラス メンバーとメソッド本体を追加します。
クラス メンバーを追加するには
コード エディターで、DeploymentReportWriter クラスに次のコードを追加します。
readonly DataSchemaModel _sourceModel; readonly ModelComparisonResult _diff; readonly DeploymentStep _planHead;
ReadOnly _sourceModel As DataSchemaModel ReadOnly _diff As ModelComparisonResult ReadOnly _planHead As DeploymentStep
重要な型は、DataSchemaModel、ModelComparisonResult、および DeploymentStep です。
次に、クラス コンストラクターに本体を追加します。
コンストラクターにメソッド本体を追加するには
次のコードをコンストラクターの本体として追加します。
if (context == null) { throw new ArgumentNullException("context"); } // save the source model, source/target differences, // and the beginning of the deployment plan. _sourceModel = context.Source; _diff = context.ComparisonResult; _planHead = context.PlanHandle.Head;
If context Is Nothing Then Throw New ArgumentNullException("context") End If ' save the source model, source/target differences, ' and the beginning of the deployment plan. _sourceModel = context.Source _diff = context.ComparisonResult _planHead = context.PlanHandle.Head
次に、WriteReport メソッドにメソッド本体を追加します。
WriteReport メソッドにメソッド本体を追加するには
WriteReport メソッドの本体として、次のコードを追加します。
// Assumes that we have a valid report file if (reportFile == null) { throw new ArgumentNullException("reportFile"); } // set up the XML writer XmlWriterSettings xmlws = new XmlWriterSettings(); // Indentation makes it a bit more readable xmlws.Indent = true; FileStream fs = new FileStream(reportFile.FullName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); XmlWriter xmlw = XmlWriter.Create(fs, xmlws); try { xmlw.WriteStartDocument(true); xmlw.WriteStartElement("DeploymentReport"); // Summary report of the operations that // are contained in the plan. ReportPlanOperations(xmlw); // You could add a method call here // to produce a detailed listing of the // differences between the source and // target model. xmlw.WriteEndElement(); xmlw.WriteEndDocument(); xmlw.Flush(); fs.Flush(); } finally { xmlw.Close(); fs.Dispose(); }
' Assumes that we have a valid report file If reportFile Is Nothing Then Throw New ArgumentNullException("reportFile") End If ' set up the XML writer Dim xmlws As New XmlWriterSettings() ' Indentation makes it a bit more readable xmlws.Indent = True Dim fs As New FileStream(reportFile.FullName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite) Dim xmlw As XmlWriter = XmlWriter.Create(fs, xmlws) Try xmlw.WriteStartDocument(True) xmlw.WriteStartElement("DeploymentReport") ' Summary report of the operations that ' are contained in the plan. ReportPlanOperations(xmlw) ' You could add a method call here ' to produce a detailed listing of the ' differences between the source and ' target model. xmlw.WriteEndElement() xmlw.WriteEndDocument() xmlw.Flush() fs.Flush() Finally xmlw.Close() fs.Dispose() End Try
重要な型は、XmlWriter および XmlWriterSettings です。
次に、ReportPlanOperations メソッドに本体を追加します。
ReportPlanOperations メソッドにメソッド本体を追加するには
ReportPlanOperations メソッドの本体として、次のコードを追加します。
// write the node to indicate the start // of the list of operations. xmlw.WriteStartElement("Operations"); // Loop through the steps in the plan, // starting at the beginning. DeploymentStep currentStep = _planHead; while (currentStep != null) { // Report the type of step xmlw.WriteStartElement(currentStep.GetType().Name); // based on the type of step, report // the relevant information. // Note that this procedure only handles // a subset of all step types. if (currentStep is SqlRenameStep) { SqlRenameStep renameStep = (SqlRenameStep)currentStep; xmlw.WriteAttributeString("OriginalName", renameStep.OldName); xmlw.WriteAttributeString("NewName", renameStep.NewName); xmlw.WriteAttributeString("Category", GetElementCategory(renameStep.RenamedElement)); } else if (currentStep is SqlMoveSchemaStep) { SqlMoveSchemaStep moveStep = (SqlMoveSchemaStep)currentStep; xmlw.WriteAttributeString("OrignalName", moveStep.PreviousName); xmlw.WriteAttributeString("NewSchema", moveStep.NewSchema); xmlw.WriteAttributeString("Category", GetElementCategory(moveStep.MovedElement)); } else if (currentStep is SqlTableMigrationStep) { SqlTableMigrationStep dmStep = (SqlTableMigrationStep)currentStep; xmlw.WriteAttributeString("Name", GetElementName(dmStep.SourceTable)); xmlw.WriteAttributeString("Category", GetElementCategory(dmStep.SourceElement)); } else if (currentStep is CreateElementStep) { CreateElementStep createStep = (CreateElementStep)currentStep; xmlw.WriteAttributeString("Name", GetElementName(createStep.SourceElement)); xmlw.WriteAttributeString("Category", GetElementCategory(createStep.SourceElement)); } else if (currentStep is AlterElementStep) { AlterElementStep alterStep = (AlterElementStep)currentStep; xmlw.WriteAttributeString("Name", GetElementName(alterStep.SourceElement)); xmlw.WriteAttributeString("Category", GetElementCategory(alterStep.SourceElement)); } else if (currentStep is DropElementStep) { DropElementStep dropStep = (DropElementStep)currentStep; xmlw.WriteAttributeString("Name", GetElementName(dropStep.TargetElement)); xmlw.WriteAttributeString("Category", GetElementCategory(dropStep.TargetElement)); } // If the script bodies are to be included, // add them to the report. if (this.IncludeScripts) { string tsqlBody = currentStep.Action(); if (string.IsNullOrEmpty(tsqlBody) == false) { xmlw.WriteCData(tsqlBody); } } // close off the current step xmlw.WriteEndElement(); currentStep = currentStep.Next; } xmlw.WriteEndElement();
' write the node to indicate the start ' of the list of operations. xmlw.WriteStartElement("Operations") ' Loop through the steps in the plan, ' starting at the beginning. Dim currentStep As DeploymentStep = _planHead While currentStep IsNot Nothing ' Report the type of step xmlw.WriteStartElement(currentStep.[GetType]().Name) ' based on the type of step, report ' the relevant information. If TypeOf currentStep Is SqlRenameStep Then Dim renameStep As SqlRenameStep = DirectCast(currentStep, SqlRenameStep) xmlw.WriteAttributeString("OriginalName", renameStep.OldName) xmlw.WriteAttributeString("NewName", renameStep.NewName) xmlw.WriteAttributeString("Category", GetElementCategory(renameStep.RenamedElement)) ElseIf TypeOf currentStep Is SqlMoveSchemaStep Then Dim moveStep As SqlMoveSchemaStep = DirectCast(currentStep, SqlMoveSchemaStep) xmlw.WriteAttributeString("OrignalName", moveStep.PreviousName) xmlw.WriteAttributeString("NewSchema", moveStep.NewSchema) xmlw.WriteAttributeString("Category", GetElementCategory(moveStep.MovedElement)) ElseIf TypeOf currentStep Is SqlTableMigrationStep Then Dim dmStep As SqlTableMigrationStep = DirectCast(currentStep, SqlTableMigrationStep) xmlw.WriteAttributeString("Name", GetElementName(dmStep.SourceTable)) xmlw.WriteAttributeString("Category", GetElementCategory(dmStep.SourceElement)) ElseIf TypeOf currentStep Is CreateElementStep Then Dim createStep As CreateElementStep = DirectCast(currentStep, CreateElementStep) xmlw.WriteAttributeString("Name", GetElementName(createStep.SourceElement)) xmlw.WriteAttributeString("Category", GetElementCategory(createStep.SourceElement)) ElseIf TypeOf currentStep Is AlterElementStep Then Dim alterStep As AlterElementStep = DirectCast(currentStep, AlterElementStep) xmlw.WriteAttributeString("Name", GetElementName(alterStep.SourceElement)) xmlw.WriteAttributeString("Category", GetElementCategory(alterStep.SourceElement)) ElseIf TypeOf currentStep Is DropElementStep Then Dim dropStep As DropElementStep = DirectCast(currentStep, DropElementStep) xmlw.WriteAttributeString("Name", GetElementName(dropStep.TargetElement)) xmlw.WriteAttributeString("Category", GetElementCategory(dropStep.TargetElement)) End If ' If the script bodies are to be included, ' add them to the report. If Me.IncludeScripts Then Dim tsqlBody As String = currentStep.Action() If String.IsNullOrEmpty(tsqlBody) = False Then xmlw.WriteCData(tsqlBody) End If End If ' close off the current step xmlw.WriteEndElement() currentStep = currentStep.[Next] End While xmlw.WriteEndElement()
重要な型は、DeploymentStep、SqlRenameStep、SqlMoveSchemaStep、SqlTableMigrationStep、CreateElementStep、AlterElementStep、および DropElementStep です。 追加ステップの型である BeginPostDeploymentScriptStep、BeginPreDeploymentScriptStep、DeploymentScriptDomStep、DeploymentScriptStep、EndPostDeploymentScriptStep、および EndPreDeploymentScriptStep は、この例では示されていません。 SQL Server 固有のステップである SqlBeginAltersStep、SqlBeginDropsStep、SqlBeginPreservationStep、SqlBeginTransactionStep、SqlEndAltersStep、SqlEndDropsStep、SqlEndPreservationStep、SqlEndTransactionStep、SqlFinalizeDatabaseAccessStep、SqlMoveSchemaStep、SqlPrintStep、SqlRenameStep、および SqlTableMigrationStep を検索することもできます。
次に、GetElementCategory メソッドの本体を追加します。
GetElementCategory メソッドにメソッド本体を追加するには
GetElementCategory メソッドの本体として、次のコードを追加します。
return _sourceModel.DatabaseSchemaProvider.UserInteractionServices.GetElementTypeDescription( element.ElementClass);
Return _sourceModel.DatabaseSchemaProvider.UserInteractionServices.GetElementTypeDescription(element.ElementClass)
重要な型およびメソッドは、DataSchemaModel、DatabaseSchemaProvider、UserInteractionServices、および GetElementTypeDescription です。
次に、GetElementName メソッドの本体を追加します。
GetElementName メソッドにメソッド本体を追加するには
GetElementName メソッドの本体として、次のコードを追加します。
return _sourceModel.DatabaseSchemaProvider.UserInteractionServices.GetElementName( element, ElementNameStyle.FullyQualifiedName);
Return _sourceModel.DatabaseSchemaProvider.UserInteractionServices.GetElementName(element, ElementNameStyle.FullyQualifiedName)
重要な型およびメソッドは、DataSchemaModel、DatabaseSchemaProvider、UserInteractionServices、GetElementName、および ElementNameStyle です。
クラスに対する変更を保存します。 次に、クラス ライブラリをビルドします。
アセンブリの署名とビルドを行うには
[プロジェクト] メニューの [MyDeploymentContributor のプロパティ] をクリックします。
[署名] タブをクリックします。
[アセンブリの署名] をクリックします。
[厳密な名前のキー ファイルを選択してください] の [<新規>] をクリックします。
[厳密な名前キーの作成] ダイアログ ボックスで、[キー ファイル] に「MyRefKey」と入力します。
(省略可能) 厳密な名前のキー ファイルにはパスワードを指定できます。
[OK] をクリックします。
[ファイル] メニューの [すべてを保存] をクリックします。
[ビルド] メニューの [ソリューションのビルド] をクリックします。
次に、アセンブリをインストールして登録し、データベース プロジェクトを配置するときに読み込まれるようにします。
配置コントリビューターのインストール
配置コントリビューターをインストールするには、次のタスクを実行する必要があります。
アセンブリおよび関連付けられた .pdb ファイルを Extensions フォルダーにコピーする。
配置コントリビューターを登録するための Extensions.xml ファイルを作成し、データベース プロジェクトを配置するときに配置コントリビューターが読み込まれるようにする。
MyDeploymentContributor アセンブリをインストールするには
MyExtensions という名前のフォルダーを %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions フォルダー内に作成します。
署名済みのアセンブリ (MyDeploymentContributor.dll) および関連する .pdb ファイルを %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions\MyExtensions フォルダーにコピーします。
注意
XML ファイルは、%Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions フォルダーに直接コピーしないことをお勧めします。 代わりにサブフォルダーを使用すると、Visual Studio Premium に用意されている他のファイルを誤って変更することを防げます。
次に、拡張機能の一種である独自のアセンブリを登録し、Visual Studio Premium に表示されるようにします。
MyDeploymentContributor アセンブリを登録するには
[表示] メニューの [その他のウィンドウ] をポイントし、[コマンド ウィンドウ] をクリックして、[コマンド] ウィンドウを開きます。
[コマンド] ウィンドウに、次のコードを入力します。 FilePath をコンパイル済みの .dll ファイルのパスとファイル名に置き換えます。 パスとファイル名は引用符で囲みます。
注意
既定では、コンパイル済みの .dll ファイルのパスは YourSolutionPath\bin\Debug または YourSolutionPath\bin\Release です。
? System.Reflection.Assembly.LoadFrom(@"FilePath").FullName
? System.Reflection.Assembly.LoadFrom("FilePath").FullName
Enter キーを押します。
作成された行をクリップボードにコピーします。 行は次のようになります。
"MyDeploymentContributor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nnnnnnnnnnnnnnnn"
プレーンテキスト エディター (メモ帳など) を開きます。
重要
Windows Vista および Microsoft Windows Server 2008 では、ファイルを Program Files フォルダーに保存できるように、エディターを管理者として開きます。
次の情報を入力し、独自のアセンブリ名、公開キー トークン、および拡張機能の型を指定します。
<?xml version="1.0" encoding="utf-8" ?> <extensions assembly="" version="1" xmlns="urn:Microsoft.Data.Schema.Extensions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:Microsoft.Data.Schema.Extensions Microsoft.Data.Schema.Extensions.xsd"> <extension type="MyDeploymentContributor.DeploymentUpdateReportContributor" assembly="MyDeploymentContributor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=<enter key here>" enabled="true" /> </extensions>
この XML ファイルを使用して、DeploymentPlanExecutor から継承するクラスを登録します。
ファイルに MyDeploymentContributor.extensions.xml という名前を付けて %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions\MyExtensions フォルダーに保存します。
Visual Studio を閉じます。
次に、データベース プロジェクトを配置してコントリビューターをテストします。
配置コントリビューターのテスト
配置コントリビューターをテストするには、次のタスクを実行する必要があります。
配置する予定の .dbproj ファイルにプロパティを追加する。
MSBuild を使用し、適切なパラメーターを指定して、データベース プロジェクトを配置する。
データベース プロジェクト (.dbproj) ファイルへのプロパティの追加
この配置コントリビューターを MSBuild から使用する場合は、ユーザーが MSBuild を使用してパラメーターを渡すことができるようにデータベース プロジェクトを変更する必要があります。 データベース プロジェクトを更新するには、任意のエディターで開き、.dbproj ファイルの最後の </ItemGroup> ノードと最後の </Project> ノードの間に次のステートメントを追加します。
<ItemGroup>
<DeploymentContributorArgument Include="GenerateUpdateReport=$(GenerateUpdateReport)" />
</ItemGroup>
.dbproj ファイルを更新した後は、MSBuild を使用してコマンド ライン ビルドのパラメーターを渡すことができます。
データベース プロジェクトの配置
データベース プロジェクトを配置して配置レポートを生成するには
Visual Studio コマンド プロンプトを開きます。 [スタート] メニューで、[すべてのプログラム]、[Microsoft Visual Studio 2010]、[Visual Studio Tools] の順にポイントし、[Visual Studio コマンド プロンプト (2010)] をクリックします。
コマンド プロンプトで、データベース プロジェクトが格納されているフォルダーに移動します。
コマンド プロンプトに次のコマンド ラインを入力します。
MSBuild /t:Rebuild MyDatabaseProject.dbproj /p:OutDir=.\
MyDatabaseProject を、ビルドするデータベース プロジェクトの名前に置き換えます。 最後にビルドした後にプロジェクトを変更した場合は、/t:Rebuild の代わりに /t:Build を使用できます。
コマンド プロンプトに次のコマンド ラインを入力します。
MSBuild /t:Deploy MyDatabaseProject.dbproj /p:GenerateUpdateReport=true
MyDatabaseProject を、配置するデータベース プロジェクトの名前に置き換えます。
次のような出力が表示されます。
Microsoft (R) Build Engine Version 4.0.20817.0
[Microsoft .NET Framework, Version 4.0.20817.0]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 8/26/2009 3:12:43 PM.
Project "C:\Users\UserName\Documents\Visual Studio 2010\Projects\MyDatabaseProject\Dep
TestToo\MyDatabaseProject.dbproj" on node 1 (Deploy target(s)).
DspDeploy:
GenerateUpdateReport=true
Deployment reports ->
C:\Users\UserName\Documents\Visual Studio 2010\Projects\MyDatabaseProject\MyDatabaseProject\sql\debug\MyTargetDatabase.summary.xml
C:\Users\UserName\Documents\Visual Studio 2010\Projects\MyDatabaseProject\MyDatabaseProject\sql\debug\MyTargetDatabase.details.xml
Deployment script generated to:
C:\Users\UserName\Documents\Visual Studio 2010\Projects\MyDatabaseProject\MyDatabaseProject\sql\debug\MyDatabaseProject.sql
Done Building Project "C:\Users\UserName\Documents\Visual Studio 2010\Projects\MyDatabaseProject\MyDatabaseProject\MyDatabaseProject.dbproj" (Deploy target(s)).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:04.02
MyTargetDatabase.summary.xml ファイルを開き、内容を調べます。
このファイルは次の例のようになり、新しいデータベース配置が示されます。
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<DeploymentReport>
<Operations>
<DeploymentScriptStep />
<DeploymentScriptDomStep />
<DeploymentScriptStep />
<DeploymentScriptDomStep />
<DeploymentScriptStep />
<DeploymentScriptStep />
<DeploymentScriptStep />
<DeploymentScriptStep />
<DeploymentScriptDomStep />
<DeploymentScriptDomStep />
<DeploymentScriptDomStep />
<DeploymentScriptDomStep />
<DeploymentScriptStep />
<DeploymentScriptDomStep />
<BeginPreDeploymentScriptStep />
<DeploymentScriptStep />
<EndPreDeploymentScriptStep />
<SqlBeginPreservationStep />
<SqlEndPreservationStep />
<SqlBeginDropsStep />
<SqlEndDropsStep />
<SqlBeginAltersStep />
<SqlPrintStep />
<CreateElementStep Name="Sales" Category="Schema" />
<SqlPrintStep />
<CreateElementStep Name="Sales.Customer" Category="Table" />
<SqlPrintStep />
<CreateElementStep Name="Sales.PK_Customer_CustID" Category="Primary Key" />
<SqlPrintStep />
<CreateElementStep Name="Sales.Orders" Category="Table" />
<SqlPrintStep />
<CreateElementStep Name="Sales.PK_Orders_OrderID" Category="Primary Key" />
<SqlPrintStep />
<CreateElementStep Name="Sales.Def_Customer_YTDOrders" Category="Default Constraint" />
<SqlPrintStep />
<CreateElementStep Name="Sales.Def_Customer_YTDSales" Category="Default Constraint" />
<SqlPrintStep />
<CreateElementStep Name="Sales.Def_Orders_OrderDate" Category="Default Constraint" />
<SqlPrintStep />
<CreateElementStep Name="Sales.Def_Orders_Status" Category="Default Constraint" />
<SqlPrintStep />
<CreateElementStep Name="Sales.FK_Orders_Customer_CustID" Category="Foreign Key" />
<SqlPrintStep />
<CreateElementStep Name="Sales.CK_Orders_FilledDate" Category="Check Constraint" />
<SqlPrintStep />
<CreateElementStep Name="Sales.CK_Orders_OrderDate" Category="Check Constraint" />
<SqlPrintStep />
<CreateElementStep Name="Sales.uspCancelOrder" Category="Procedure" />
<SqlPrintStep />
<CreateElementStep Name="Sales.uspFillOrder" Category="Procedure" />
<SqlPrintStep />
<CreateElementStep Name="Sales.uspNewCustomer" Category="Procedure" />
<SqlPrintStep />
<CreateElementStep Name="Sales.uspPlaceNewOrder" Category="Procedure" />
<SqlPrintStep />
<CreateElementStep Name="Sales.uspShowOrderDetails" Category="Procedure" />
<SqlEndAltersStep />
<DeploymentScriptStep />
<BeginPostDeploymentScriptStep />
<DeploymentScriptStep />
<EndPostDeploymentScriptStep />
<DeploymentScriptDomStep />
<DeploymentScriptDomStep />
<DeploymentScriptDomStep />
</Operations>
</DeploymentReport>
注意
ターゲット データベースと同一のデータベース プロジェクトを配置した場合、生成されるレポートはあまり意味がありません。 意味のあるレポートを得るには、データベースに対する変更を配置するか、新しいデータベースを配置します。
MyTargetDatabase.details.xml ファイルを開き、内容を調べます。
詳細ファイルの小さいセクションは、Sales スキーマを作成するエントリとスクリプト、テーブルの作成に関するメッセージを出力するエントリとスクリプト、およびテーブルを作成するエントリとスクリプトを示しています。
<CreateElementStep Name="Sales" Category="Schema"><![CDATA[CREATE SCHEMA [Sales]
AUTHORIZATION [dbo];
]]></CreateElementStep>
<SqlPrintStep><![CDATA[PRINT N'Creating [Sales].[Customer]...';
]]></SqlPrintStep>
<CreateElementStep Name="Sales.Customer" Category="Table"><![CDATA[CREATE TABLE [Sales].[Customer] (
[CustomerID] INT IDENTITY (1, 1) NOT NULL,
[CustomerName] NVARCHAR (40) NOT NULL,
[YTDOrders] INT NOT NULL,
[YTDSales] INT NOT NULL
);
]]></CreateElementStep>
配置計画を実行しながら分析することにより、配置に含まれている情報を報告し、その計画のステップに基づいて追加のアクションを実行できます。
次の手順
追加のツールを作成して、出力 XML ファイルの処理を実行することもできます。 これは、DeploymentPlanExecutor の一例に過ぎません。 配置計画を実行前に変更する DeploymentPlanModifier を作成することもできます。
参照
概念
その他の技術情報
ビルド コントリビューターおよび配置コントリビューターを利用してデータベースのビルドおよび配置をカスタマイズする