Visual Studio のデータベース機能の拡張

拡張機能を作成することにより、Visual Studio Premium や Visual Studio Ultimate を拡張できます。 拡張機能によって、リファクタリング、データ生成、単体テスト、データベース コード分析などの Visual Studio Premium や Visual Studio Ultimate の機能を拡張できます。 拡張機能を作成するときには、基本となる機能の既存のフレームワークを使用するため、新たに記述するコードは大幅に減少します。

拡張機能には、正しく定義された機能拡張ポイントがあります。 Visual Studio Premium または Visual Studio Ultimate の拡張機能を作成するために、Visual Studio SDK は必要ありません。

共通の概要タスク

高度なタスク

関連する参照先

データベース機能拡張の概念を理解する: Visual Studio Premium や Visual Studio Ultimate の機能を拡張する前に、これらのアプリケーションで機能拡張がどのように動作するのかを理解する必要があります。 データベース スキーマ プロバイダーは、データベースの特定のブランドまたはバージョンに固有のサービス (SQL Server 2008 など) をすべて実装します。 これには、データベースのスクリプトの読み取りおよび書き込みを行うパーサー、スクリプトを表すスクリプト ドメイン オブジェクト モデル (スクリプト DOM)、データベース オブジェクトのオブジェクト、リレーションシップ、およびプロパティをモデル化するスキーマ モデルが含まれます。 Visual Studio Premium または Visual Studio Ultimate では、機能または拡張機能を操作する場合、それらの機能または拡張機能は、DSP サービス、スクリプト DOM、およびスキーマ モデルの組み合わせを基礎として動作します。

  • データベースのモデル化

  • Database Edition の機能拡張コンポーネント

  • 拡張機能の種類

  • データベース スキーマ プロバイダーのコア コンポーネント

新しいデータベース リファクタリングの種類のサポートを追加する: データベース リファクタリングの拡張機能を作成することにより、新しいデータベース リファクタリングの種類を使用可能にできます。 新しいリファクタリングの種類には、それぞれ 1 つ以上の新しいリファクタリング コントリビューターも必要です。

データベース リファクタリングの新しいターゲットのサポートを追加する: 既存のデータベース リファクタリングの種類を有効にすることにより、テキスト ファイルなどの新しい種類の成果物やデータベース情報が格納されたサードパーティ アプリケーションの出力を更新できます。 新しいリファクタリングの種類を作成する場合は、1 つ以上のリファクタリング コントリビューターを実装して、そのリファクタリングの種類がデータベース プロジェクト内の成果物に対して操作を実行できるようにする必要があります。

新しいデータベース コード分析規則を定義する: Visual Studio Premium または Visual Studio Ultimate に定義されている規則では検出されない問題を見つけ出す新しいデータベース コード分析規則を定義できます。

カスタム データ ジェネレーターを作成する: カスタム データ ジェネレーターを使用して、重要情報を公開しない現実的なテスト データを生成できます。 Visual Studio Premium または Visual Studio Ultimate に含まれるデータ ジェネレーターを補完するカスタム データ ジェネレーターを作成できます。

カスタム データベース単体テスト条件を追加する: カスタム テスト条件を追加することにより、組み込みの単体テスト条件の対象とならないデータベース オブジェクトの動作を確認できます。

データベース プロジェクトの動作をカスタマイズする: カスタムのデータベース プロジェクト機能を定義することにより、組み込みのデータベース プロジェクトでサポートされていない方法でプロジェクトの動作を変更できます。

データベースのモデル化

データベースをモデル化するためには、Visual Studio によって、データベースのデータ定義言語 (DDL) を構成するスクリプトと、そのスクリプトの実行によって生成されるデータベースの両方をモデル化します。 DDL スクリプトのモデルはスクリプト DOM によって提供されます。 作成されるデータベースのモデルはスキーマ モデルによって提供されます。

機能拡張コンポーネント間のデータ フロー

次の図は、これらのコンポーネント間でデータがどのように移動するのかを示しています。

機能拡張コンポーネント間のデータ フロー

機能拡張コンポーネント間のデータ フロー

データベース オブジェクトの定義は、データベース プロジェクト内で DDL スクリプトとして永続化されます。 データベース プロジェクトを開くと、それらのスクリプトが読み込まれ、スクリプト DOM モデルとスキーマ モデルのデータが作成されます。 Visual Studio Premium の機能は、この 2 つのモデルと対話し、データベース オブジェクトに変更を保存すると、それらの変更が再び DDL スクリプト内で永続化されます。

Database Edition の機能拡張コンポーネント

次の図は、相互に対話して Database Edition の機能拡張を実現するコンポーネントを示しています。

機能拡張コンポーネント間の通信

Database Edition の機能拡張コンポーネント

データベース プロジェクトを開いたり作成したりすると、拡張機能マネージャー コンポーネントが登録済みのデータベース スキーマ プロバイダーを読み込みます。 データベース スキーマ プロバイダー (DSP) に対して特定の機能を使用するときには、拡張機能マネージャー コンポーネントがそれらの機能とその DSP をサポートする拡張機能を読み込みます。 たとえば、名前の変更リファクタリング機能を使用して SQL Server 2008 データベース内のオブジェクトの名前を変更するときには、リファクタリング機能と共に、SQL Server 2008 用のリファクタリングの種類とコントリビューターが読み込まれます。

拡張機能マネージャー

Visual Studio Premium または Visual Studio Ultimate の実行時には、すべてのデータベース プロジェクト、スキーマ プロバイダー、機能、および拡張機能がシングルトン ExtensionManager と対話します。 拡張機能マネージャーは、データベース プロジェクトごとに、DatabaseSchemaProvider から派生した 1 つのインスタンスを読み込みます。 たとえば、Visual Studio Premium または Visual Studio Ultimate が Microsoft SQL Server 2005 プロジェクトを開くと、拡張機能マネージャーが Sql90DatabaseSchemaProvider のインスタンス (DatabaseSchemaProvider から派生) を読み込みます。

拡張機能マネージャーは、拡張機能によって実装されるインターフェイスの種類に基づいて拡張機能を読み込みます。 たとえば、データベース単体テスト機能を使用するときには、拡張機能マネージャーが、TestCondition 基本クラスを継承する登録済み拡張機能のリストを返します。これらの拡張機能は、データベース プロジェクトのデータベース スキーマ プロバイダーと互換性があります。

拡張機能の互換性

リファクタリングやスタティック コード分析などの機能は、DSP に固有のコンポーネントとすべての DSP をサポートするコンポーネント (DSP に依存しないコンポーネント) で構成されます。 拡張機能を定義するときには、拡張機能が適切なプロジェクトの種類に対してのみ読み込まれるように、拡張機能と特定の DSP または基本 DSP との互換性を宣言します。 たとえば、拡張機能に Sql90DatabaseSchemaProvider (拡張機能の対象を SQL Server 2005 プロジェクトに限定) または SqlDatabaseSchemaProvider  (SQL Server 2005 および SQL Server 2008 DSP の基本クラス) との互換性があることを宣言できます。 また、拡張機能に複数の特定の DSP との互換性があることを宣言することもできます。 このアプローチは、拡張機能が将来のリリースに対応できるかどうか不確かである場合などに役立ちます。 機能にすべての DSP との互換性があることを宣言するには、DatabaseSchemaProvider 基本クラスとの互換性があることを宣言します。

1 つの DSP と互換性のある拡張機能を定義します。

// SqlSchemaObjectDesigners is defined as compatible with all Sql 
// database services providers.  
[DatabaseSchemaProviderCompatibility (typeof(Sql90DatabaseSchemaProvider))]
internal class SqlSchemaObjectDesigners : ISchemaObjectDesigners
{
}

複数の DSP と互換性のある拡張機能を定義します。

// Extension InconclusiveCondition is defined as compatible with all 
// SQL Server database services providers and Oracle database 
// services providers.
[DatabaseSchemaProviderCompatibility (typeof(SqlDatabaseSchemaProvider))]
[DatabaseSchemaProviderCompatibility (typeof(OracleDatabaseSchemaProvider))]
public sealed class InconclusiveCondition : TestCondition
{
}

すべての DSP と互換性のある拡張機能を定義します。

// Extension ReportingService is defined as compatible with all
// database services providers.
[DatabaseSchemaProviderCompatibility (typeof(DatabaseSchemaProvider))]
internal class ReportingService : IReportingService
{
}

いずれの DSP とも互換性のない拡張機能を定義します。

// Extension ExecutionTimeCondition is defined as compatible with no
// database services providers.  That means if a feature
// has an ExtensionManager constructed with null, it will load
// those extensions defined as binding to 
// DspCompatibilityCategory.None
[DatabaseSchemaProviderCompatibility (DspCompatibilityCategory.None)]
public sealed class ExecutionTimeCondition : TestCondition
{
}

拡張機能の種類

Visual Studio Premium や Visual Studio Ultimate のさまざまな機能の能力を強化する拡張機能を作成できます。 次の表では、作成できる拡張機能の種類について説明します。

機能

拡張機能の種類

説明

データベース単体テスト

単体テスト条件

テストの成否を決定するカスタム アサーションを追加できます。 単体テスト API の多くはパブリックですが、それ自体が機能拡張ポイントに相当するわけではありません。 これらの API は、Visual C# や Visual Basic などのマネージ コードで記述されたデータベース単体テストを作成するために使用されます。 詳細については、「データベース単体テストのカスタム条件の定義」を参照してください。

データ生成

データ ジェネレーター

Visual Studio Premium または Visual Studio Ultimate にデータ ジェネレーターが用意されている場合は、機能拡張 API を使用してカスタム データ ジェネレーターを作成できます。 詳細については、「カスタム データ ジェネレーターを使用した特殊なテスト データの生成」を参照してください。

データベース コード分析

コード分析規則

データベース コード内の特定の問題をチェックする独自のコード分析規則を定義できます。 詳細については、「データベース コード分析用の追加規則の作成と登録」を参照してください。

データベース リファクタリング

リファクタリング ターゲット

既存のリファクタリングの種類を拡張して、新しいファイルの種類などの新たなターゲットを操作の対象とすることができます。 詳細については、「チュートリアル: データベースの名前変更リファクタリングを拡張してテキスト ファイルで動作させる」を参照してください。

データベース リファクタリング

リファクタリングの種類

入れ子になった条件記述をガード句に置き換えるリファクタリングなど、新しいリファクタリングの種類を作成できます。 詳細については、「カスタムのデータベース リファクタリングの種類またはターゲットの作成」を参照してください。

データベース スキーマ プロバイダーのコア コンポーネント

データベース スキーマ プロバイダー (DSP) は、次の 3 つのコンポーネント グループで構成されます。

  • スクリプト DOM — DDL ステートメントと DML ステートメントの両方を含む任意の SQL スクリプトをモデル化するオブジェクト モデルとサポート サービス

  • スキーマ モデル — テーブル、ビュー、ストアド プロシージャなど、データベース インスタンス内のオブジェクトをモデル化するオブジェクト モデルとサポート サービス

  • ユーザー対話サービス — コア コンポーネントに、オブジェクト名を表す文字列、オブジェクトの種類およびカテゴリを表すアイコン、それらのオブジェクトを表示する階層構造などのユーザー インターフェイス リソースへのアクセスを提供するサービスのコレクション

DSP の主要な機能は、DDL スクリプトをスクリプト DOM とスキーマ モデルの両方で表現できるようにすることと、この 2 つのモデル表現からスクリプトを再生成する逆方向の機能を実現することです。

スクリプト DOM

スクリプト DOM は、DDL スクリプトを解析して、そのスクリプトを表すオブジェクト モデルにする実装を提供します。 スクリプト DOM は、モデルから元のスクリプトを再現する実装も提供します。

次の図は、スクリプト DOM との間でデータがどのように移動するのかを示しています。

スクリプト DOM とのデータ フロー

スクリプト DOM とのデータ フロー

スクリプト DOM パーサーは、構造化されていないテキスト ファイルに保存されたスクリプトを、IScriptFragment インターフェイスを継承するオブジェクトに変換します。 スクリプト DOM のスクリプト ジェネレーターは、IScriptFragment インターフェイスを継承するオブジェクトから元のスクリプトを生成します。 Visual Studio Premium または Visual Studio Ultimate に含まれる、SQL Server のデータベース スキーマ プロバイダーでは、IScriptFragment が抽象構文ツリー (AST: Abstract Syntax Tree) とトークン ストリームを抽象化します

トークンは、スクリプトの構造化されていない表現を提供します。 コレクション内の各トークンには、次の情報が含まれます。

  • トークンの種類 (キーワードやリテラル文字列など)

  • トークン文字列

  • トークンが出現したソース ファイル

  • ソース ファイル内でのトークンの出現位置のオフセット

AST は、スクリプトの構造を表すものです。 AST の各ノードは、バッチ ステートメント、ステートメント、またはステートメントのコンポーネント (式など) を表します。 AST は、解析が完了したスクリプトの分析に使用されます。 また、スクリプトをプログラムによってビルドするときにも AST が使用されます。

スキーマ モデル

スキーマ モデル表現は、ライブ データベース インスタンスをモデル化するインターフェイス ベースのオブジェクト モデルです。 各インターフェイスは、すべての DSP が共有する 1 つの抽象レイヤーと、より具体的なモデルの詳細を対象とする任意の数の抽象レイヤーが含まれた派生階層に配置されます。 たとえば、ISql90Table インターフェイスは ISqlTable を継承し、ISqlTable は IDatabaseTable 抽象レイヤー インターフェイスを継承します。 スキーマ モデルは、IScriptFragment オブジェクトを取得してスキーマ モデル要素に変換し、さらにスキーマ モデル要素から IScriptFragment オブジェクトへの逆方向の変換も実行します。 スキーマ モデルは複数のモデル コンポーザー実装で構成されます。 各実装でシステム内の他のリソースからモデルが作成されます。 たとえば、ScriptModelComposer は、データベース プロジェクト内のスクリプト ファイルからモデルを構成します。

スキーマ モデル インフラストラクチャ (ModelStore とそのサポート クラス) は、統合 Script DOM 参照をモデル要素から直接実装します。 これにより、任意のスクリプトを含むオブジェクト (ストアド プロシージャなど) のモデル化が可能になります。

スキーマ モデルは、要素と注釈のコレクションで構成されます。 要素は、モデル化される成果物 (テーブル、ビュー、ストアド プロシージャ、トリガー、列など) を示します。 注釈は、任意のデータをモデルに関連付けるために使用されます。 注釈は、データベース プロジェクトのコア コンポーネントによって使用され、プロジェクト機能や拡張機能で使用することもできます。 要素と注釈は、名前を付けることも匿名にすることもできます。

モデル要素

要素は、プロパティとリレーションシップで構成されます。 プロパティは、整数、ブール値、文字列などの基本データを表し、モデルの詳細を取得するために使用されます。 リレーションシップは、要素間の型指定された名前付きの接続を表します。 たとえば、ISqlTable 要素には、テーブルとその列を関連付ける "Columns" という名前の ISqlColumn 型のリレーションシップがあります。

リレーションシップには、次の 3 つの基本的な種類があります。

  • ピア — ある要素と別の要素の依存関係を任意の方法で表します。 SQL Server では、ビューとテーブル間のリレーションシップがピア リレーションシップとしてのモデル化に最も適しています。

  • 構成 — 他の要素で構成される 1 つの要素を表します。 SQL Server では、テーブルとその列とのリレーションシップが構成リレーションシップとしてのモデル化に最も適しています。 構成リレーションシップの基本原則の 1 つは、2 つの要素が 1 つのアクションとして同時に作成されることです。 要素間には、作成または削除に関して依存関係の順序はありません。 ただし、結合性のある依存関係を実現するために、モデルでは親から子という依存関係の方向が維持されます。 たとえば、列に特定の型による依存関係がある場合、親テーブルの列への依存関係により、テーブルもその型に依存することを意味します。

  • 階層 — 階層構造を表します。 階層リレーションシップは、依存関係の方向が (親から子ではなく) 子から親である点で、構成リレーションシップと異なります。 SQL Server での階層リレーションシップの例は、スキーマと所有されているオブジェクト (テーブルやビューなど) とのリレーションシップです。 テーブルは、そのスキーマとの階層リレーションシップに参加します。

次の図は、スキーマ モデルで表すことができる 3 種類のリレーションシップを示しています。

スキーマ モデルでのオブジェクト リレーションシップ

スキーマ モデルでのオブジェクト リレーションシップ

モデル内の各リレーションシップでは、多重リレーションシップと単一リレーションシップのどちらであるかを宣言します。 どの場合でも、要素は空のリレーションシップを保持できます。 モデルは、実際の成果物の不完全なモデルであってもかまいません。

要素は、ストア実装で次の機能をサポートするためにインターフェイスに基づいています。

  • 要素の厳密な型指定 (ID)

  • 多重継承

    • システムの DSP に依存しない部分と DSP 固有の部分の両方をサポートするため

    • 関連のない要素の型の間で "品質" の共有をサポートするため

  • バージョンの柔軟性と拡張性

すべてのモデル要素クラスは、IModelElement パブリック インターフェイスを実装します。 プロパティ、リレーションシップ、および注釈には、このクラスの ModelStore メタデータ API を使用してアクセスできます。 IDatabaseTable などのインターフェイスを使用すると、より簡単で保守が容易な方法でプロパティとリレーションシップにアクセスできるようになります (コンパイル時にバインドされます)。

モデル注釈

注釈は、要素と同様に、複数のプロパティで構成されます。 要素とは異なり、注釈はリレーションシップに参加しません。 そうではなく、注釈は要素またはモデル ストア自体にアタッチされます。 注釈は厳密に型指定され、注釈の 1 つのインスタンスをモデル ストアだけでなく複数の要素にアタッチできます。 モデルにアタッチされた注釈は、そのモデルに対して "グローバル" である注釈インスタンスを表します。