ADO.NET 2.0 の機能マトリックス

Bob Beauchemin
DevelopMentor

July 2004

適用対象:
   Microsoft ADO.NET 2.0
   Microsoft SQL Server 2005

概要: ADO.NET 2.0 には、新しい基本クラス プロバイダ モデル、すべてのプロバイダに対する機能、System.Data.SqlClient に対する変更が含まれます。これらの新しい機能の概要、その使用例、およびプロバイダ中立の機能と SqlClient 固有の機能を示す表を確認します。

目次

基本クラスベースのプロバイダ モデル
接続プールの機能拡張
非同期コマンド
一括インポート
プロバイダ統計
AttachDbFileName
SqlClient における SQL Server 2005 固有の機能
まとめ

ADO.NET 2.0 は、新しい機能が満載されています。 これには、すべてのプロバイダが利用できる新しい基本クラスベースのプロバイダ モデルおよび機能と、System.Data.SqlClient に固有の変更が含まれています。 .NET Framework 2.0 は SQL Server 2005 と組み合わせてリリースされているため、これらの機能の一部を使用するには SQL Server 2005 を使用できるようにする必要があります。 この記事は、新しい機能の概要とロードマップを示すために用意され、使用例を提供し、どの機能がプロバイダ中立であり、どの機能が SqlClient 固有かを示す表を掲載しています。 この連続記事では、これから、一部の機能についてより詳細に説明していく予定です。 また、DataSet とフレンドのさまざまな新しい機能があります。これらについては、将来の記事で説明します。

基本クラスベースのプロバイダ モデル

ADO.NET 1.0 および 1.1 では、プロバイダ開発者によって、一連のプロバイダ固有のクラスが実装されていました。 各クラスが汎用的なインターフェイスを実装していたため、汎用的なコーディングが可能でした。 たとえば、System.Data.SqlClient にはクラス SqlConnection が含まれ、このクラスは IDbConnection を実装します。 System.Data.OracleClient には、クラス OracleConnection が含まれ、このクラスも IDbConnection を実装します。 プロバイダ固有のクラスは、データ ソース固有のプロパティとメソッドを実装できました。たとえば、SqlConnection は Database プロパティと ChangeDatabase メソッドを実装します。 Oracle データベースでは、1 つのデータベース インスタンスごとに "複数のデータベース" (これらは ANSI SQL ではカタログと呼ばれる) という概念がないため、OracleConnection はこのようなプロパティやメソッドを実装しません。 ADO.NET 2.0 の新しいプロバイダ モデルは、System.Data.Common 内の一連の基本クラスに基づきます。 これらは一般的な機能の基本的な実装を提供し、もちろん、各基本クラスは、下位互換性を保つために依然として必要とされる汎用的なインターフェイスを実装します。 プロバイダ開発者は、基本クラスを使用するか、インターフェイスをサポートするかを選択できます。

以前のバージョンではインターフェイス モデルに対する例外として、DataAdapter/DbDataAdapterCommandBuilder の 2 つがありました。 CommandBuilder クラスは、単純な SELECT コマンドに対して、同じ列セットを使用する INSERT、UPDATE、および DELETE コマンドの自動実装を提供します。 SqlCommandBuilder はシール クラスだったため、CommandBuilder がアクション ステートメントを作成するために使用した基本アルゴリズムを維持したまま CommandBuilder を拡張することはできませんでした。 まだ SqlCommandBuilder パラメータ パーサーを再利用する方法はありませんが、System.Data.Common の中には DbCommandBuilder 基本クラスがあります。 これらのクラス内には基本クラス レベルで公開される新しい機能もあります。 DataAdapter/DbDataAdapter 基本クラスは、SQL Server SqlTypes などのプロバイダ固有の型を DataSet にプッシュするメカニズム (ReturnProviderSpecificTypes プロパティ)、およびバッチ更新を行うメカニズム (StatementType.Batch 列挙値と UpdateBatchSize プロパティ) を公開します。 DbCommandBuilder 共通基本クラスには、同時実行ポリシーの選択を示すプロパティ (ConflictDetection プロパティ) が含まれます。

プロバイダ ファクトリ

ADO.NET 1.0 および 1.1 におけるインターフェイスベースのアプローチの複雑さは、ユーザーがインターフェイス上でコンストラクタを呼び出すことができない点にあります。 特定のクラスの具体的なインスタンスを作成する必要があります。 OLE DB および ADO などの以前の API は、接続文字列をオーバーロードすることによって、この周囲で動作しました。 接続文字列には、プロバイダの COM PROGID が含まれ、正しい DataSource クラスはこの PROGID に基づいて作成されました。 これは、OLE DB DataSource PROGID がレジストリに格納されていたので可能でした。

' VB6 ADO コード、Connection はインターフェイス (実際には _Connection)
Dim conn as Connection
' 既定のプロバイダは ODBC に対する OLE DB プロバイダである MSDASQL であることに注意します
' これは SQL Server に対する OLE DB プロバイダを使用します
conn.ConnectionString = "provider=sqloledb;.."  ' その他のパラメータは削除
conn.Open

ADO.NET 2.0 では、この点に対する解決策があります。 各データ プロバイダは、.NET machine.config 内に ProviderFactory クラスと プロバイダ文字列を登録します。基本 ProviderFactory クラス (DbProviderFactory)、および machine.config に登録されたさまざまなデータ プロバイダに関する情報の DataTable を返し、プロバイダ文字列 (ProviderInvariantName と呼ばれる) または DataTable から DataRow を指定すると正しい ProviderFactory も取得することもできる、System.Data.Common.ProviderFactories クラスがあります。 条件付きコードは、次のように記述されていました。

enum provider {sqlserver, oracle, oledb, odbc};
// 構成からプロバイダを決定します
provider prov = GetProviderFromConfigFile();
IDbConnection conn = null;
switch (prov) {
  case provider.sqlserver: 
    conn = new SqlConnection(); break;
  case provider.oracle:     
    conn = new OracleConnection(); break;
  case provider.oledb:      
    conn = new OleDbConnection(); break;
  case provider.odbc:       
    conn = new OdbcConnection(); break;
  // アプリケーションが新しいプロバイダをサポートするため、これらを追加します 
}

現在は次のように記述されます。

// 構成から ProviderInvariantString を取得します
  string provstring = GetProviderInvariantString(); 
  DbProviderFactory fact = DbProviderFactories.GetFactory(provstring);
  IDbConnection = fact.CreateConnection();  

コンピュータにインストールしたデータ プロバイダ、およびそれぞれの ProviderFactory を検索する標準が出現したことにより、その他の興味深い可能性につながります。

サーバー列挙

machine.config にプロバイダの構成を入力すると、このプロバイダがサポートする基本クラスまたは基本インターフェイスはどれかを示すビットマスクが指定されます。 これは、一部のデータ プロバイダは System.Data.Common 内の一部の機能をサポートする必要がないためです。たとえば、CommandBuilder はあることが望ましいクラスですが、なくても特に問題はありません。

DbEnumerator は、ADO.NET 2.0 の構成に追加された新しい基本クラスです。 このクラスは、このクラスをサポートするデータ プロバイダがデータ ソースの一覧を取得できるようにします。 たとえば、SqlClient がこのクラスをサポートすると、ネットワーク上で使用できる SQL Server インスタンスの一覧が返されます。 これによって、プログラムとツールにおいて、ユーザーがデータ ソースを選択できるようになります。 これを使用するツールの一例が、Visual Studio 2005 です。

接続文字列ビルダとメタデータ スキーマ

Visual Studio .NET では、従来、OLE DB コンポーネントを使用して接続文字列をビルドし、データ ソースを表していました。 Visual Studio 2005 でサーバー エクスプローラを使用して、Visual Studio .NET 2003 に新しいデータ接続を追加すると、OLE DB 接続文字列ビルダが表示され、.NET データ プロバイダではなく、コンピュータにインストールされた OLE DB プロバイダの一覧が表示されます。 これによって、その後は (OLE DB プロバイダではありますが) プロバイダを選択し、対応するプロバイダに対する ADO.NET 接続文字列をビルドできます。 Visual Studio 2005 では、前に説明した DbProviderFactories によって .NET データ プロバイダの一覧が表示され、DbConnectionStringBuilder というクラスがグラフィック ユーザー インターフェイス コンポーネントによって使用されることにより、プログラマは接続文字列をグラフィカルにビルドし、構成ファイルから接続文字列を読み込み、保存することができます。

Visual Studio 2005 サーバー エクスプローラによって、表示対象となるテーブル、列、ビュー、およびストアド プロシージャの一覧などのデータ ソース メタデータも取得されます。 ANSI SQL 仕様には、このメタデータに対する基本仕様があります。これは INFORMATION_SCHEMA ビューと呼ばれています。 これらの汎用的なビューは、初めて作成するものとしては適していますが、データベース固有のビューまたは情報を使用して拡張する必要がでてくる場合があります。 ADO.NET 2.0 では、すべてのデータベースは INFORMATION_SCHEMA ビューをサポートしていないため、データ プロバイダによって、使用できるメタデータ、およびそのメタデータをデータベースから取得する方法を一覧表示する XML 形式の構成ファイルを提供できます。 これは、ツールのプログラマがプロバイダ定義による情報の拡張セットを取得するのに大きく役立ちます。 プロバイダ モデルに対する拡張の詳細については、将来の記事で説明します。

トレース

プログラマおよびサポート スタッフがデータベース API の呼び出しをトレースできるようにしておくと、ユーザーからの説明やプログラムからのエラー メッセージがあった場合に、データ アクセス スタック内の問題がある場所を判断するのに非常に役立ちます。 通常、問題は次の原因によって発生する可能性があります。

  1. クライアントのプログラムと実際のデータベースとの間のスキーマの不一致
  2. データベースが使用不可である、またはネットワーク ライブラリの問題
  3. ハードコーディングされた、またはアプリケーションによって生成された、間違った SQL
  4. 間違ったプログラミング ロジック

従来は、トレースを許可するコードを実装するかどうかは各プロバイダ開発者の決定に委ねられていましたが、ODBC などの一部の API では、事実上の標準が存在します。 標準の OLE DB トレースを行わないと、OLE DB および ADO の問題の解決がより困難になります。 これは ADO.NET のみのアーキテクチャではありませんが、ADO.NET 2.0 の Microsoft のプロバイダは、汎用トレースと実装 API を利用します。 この新しい機能を使用すると、アプリケーション スタックの任意のレベルで問題をトレースできます。 実装された Microsoft ADO.NET プロバイダだけではなく、データ アクセス スタックのその他の部分もこの機能を使用し、また、この機能を使用できるのは実装を行うプロバイダ開発者だけです。 ADO.NET 2.0 DataSet と関連するクラスでも、組み込みの診断機能があります。 トレースの詳細については、将来の記事で説明する予定です。

SqlClient の拡張機能

Microsoft の最上位のデータベースは、SQL Server であり、SqlClient は SQL Server 固有のプロバイダです。 ADO.NET 2.0 は、実際 4 つの Microsoft プロバイダとともに出荷されます。

  1. SqlClient?SQL Server 用の Microsoft プロバイダ
  2. OracleClient?Oracle データベース用の Microsoft プロバイダ
  3. OleDb?ADO.NET で OLE DB プロバイダを使用するためのブリッジ プロバイダ
  4. Odbc?ADO.NET で ODBC ドライバを使用するためのブリッジ プロバイダ

ADO.NET 2.0 では、これらのプロバイダのすべてが拡張され、部分的に信頼された環境でそれぞれを使用できるようになりました。 .NET コード アクセス セキュリティ (CAS) を適切に構成することにより、さらにデータを中心としたモバイル コード シナリオが可能になる可能性があります。 ADO.NET 1.1 では、この機能をサポートしていたのは SqlClient プロバイダだけでした。

また、データ プロバイダは、データベース会社 (Oracle の ODP.NET と IBM の DB2 データ プロバイダ) プロバイダの専門家 (DataDirect Technologies)、オープン ソース プロジェクト、および個人によって記述されます。 また、Microsoft は Host Integration Server 2004 製品で DB2 データ プロバイダを出荷する予定です。

さまざまなソフトウェアの中でも SQL Server は重要な役割を持つため、すべての Microsoft によってサポートされているプロバイダにおける機能拡張に加え、ADO.NET 2.0 の SqlClient に対する多数の機能拡張があります。 新しい機能の多くが SQL Server 2005 (コード ネーム "Yukon") で使用可能なさまざまな新しい機能をサポートするようになっていますが、この機能の一部は、SQL Server のすべてのバージョンをサポートします。 SQL Server 2005 はサーバーの内部で実行中の .NET コードをサポートします。プロバイダ モデルを使用してサーバーの内部でデータ アクセスの最適化も行われます。 すぐには気付きにくい内部における大きな変更点としては、ADO.NET 2.0 内の SqlClient データ プロバイダは Microsoft Data Access Components (MDAC) を使用しないということが挙げられます。 また、ネットワーク エラーについてのより明確なエラー メッセージと全体により詳細なエラー メッセージが用意されたことにより、プロバイダのエラー処理も向上します。 ここでは、プログラマに表示される SqlClient 固有の機能の概要を示します。

接続プールの機能拡張

ADO.NET 1.0 では、データベース接続をプールするための新しいインフラストラクチャが導入されました。 Microsoft の SqlClient データ プロバイダと OracleClient データ プロバイダは、このインフラストラクチャを使用します。OleDb データ プロバイダと Odbc データ プロバイダは使用しません。 新しいプール メカニズムによって、接続プール パラメータのきめ細やかなサポートが実現されました。このパラメータには、最小および最大プール サイズや、接続がプール内で使用可能になるまでプール マネージャが待機する機能 (待機時間はユーザーが定義) が含まれます。 ADO.NET では、接続プールの機能拡張が追加されます。この機能拡張により、プログラムによって接続プールを "ドレイン"、つまり、現在プールの実行者によって起動されているすべての接続を閉じることができます。 (Visual Basic .NET で共有される) 静的メソッド SqlConnection.ClearPool を使用して特定の接続プールを消去したり、SqlConnection.ClearPools メソッドを使用して appdomain 内のすべての接続プールを消去したりできます。 SqlClient と OracleClient は両方ともこの機能を実装します。

非同期コマンド

クライアントまたはミドルウェアのコードでは、複数のことを同時に実行しなければならない場合があります。 本質的にマルチスレッド化されたミドルウェア コードでは、これはスループットの増大の重要な要因になります。 ADO.NET 2.0 では、現在、SqlClient によって非同期コマンドの実行がサポートされています。

非同期操作に対する .NET パラダイムは、同期操作に対して 1 つのメソッドを提供する場合と同様に、特定の操作に対する Begin メソッドと End メソッドを提供することです。 データベース コマンドの実行には長い時間がかかる可能性があるため、現在は SqlClient によって、非同期実行を提供する組み込みの SqlCommand メソッドが提供されます。 非同期実行とそれに相当する同期実行をサポートするメソッドを次の表に示します。

同期メソッド 非同期メソッド
ExecuteNonQuery BeginExecuteNonQuery、EndExecuteNonQuery
ExecuteReader BeginExecuteReader、EndExecuteReader
ExecuteXmlReader BeginExecuteXmlReader、EndExecuteXmlReader

非同期実行は便利に使用できる機能ですが、特に理由もなく多用することは避けてください。コマンドを長時間実行する可能性があり、同時に実行すると便利なものもある場合にのみ、使用します。 オペレーティング システムの Windows NT ファミリに含まれる Windows スレッド スケジューラ (Windows 9x および Me のクライアントでは使用できない機能) は、スレッド間の切り替えに独自のオーバーヘッドがかかります。 また、一部の .NET ライブラリは、スレッド依存であることに注意してください。非同期に使用する場合は、操作を開始するために使用するスレッドは、操作を完了するために使用するスレッドと同じものである必要はありません。 ただし、SQL Server ネットワーク ライブラリ スタックは I/O 完了ポートを使用して非同期をサポートするために拡張され、これによって非同期 SQL Server 操作のスループットが向上します。 非同期操作は複数のアクション ステートメントとストアド プロシージャの実行だけに効果的なのではなく、SQL Server 2005 の multiple active resultset feature とともに使用すると、単一のデータベース接続を使用して非同期 SELECT ステートメントを多重化することもできます。

一括インポート

多くのデータベース アプリケーションでは、大規模なバッチによって、すばやく複数の行を SQL Server に挿入できます。 このような使い方の標準的な例は、電話スイッチまたは病院の患者モニタなどのハードウェア デバイスからの読み取りに対応する SQL Server に、アプリケーションによって複数の行を挿入する場合が挙げられます。 SQL Server には、このような操作に対応するためのユーティリティ (bcp など) が付属し、これらは通常ファイルを使用して入力を行います。

SqlClient には、新しい SqlBulkCopy という名前のクラスが含まれます。 このクラスは、ファイルから入力を直接処理したり、BCP などの ファイル出力を作成するためのものではありませんが、クライアントからデータベースへの複数の行の挿入をすばやく効率的に行えるようにします。 SqlBulkCopy は、DataReaders と DataSets から入力を取得できます。 つまり、プロバイダから一連の行を直接ストリーム配信できるだけではなく (DataReader)、プロバイダではないハードウェア デバイスから取得した外部データを DataSets に格納し、これを直接更新することもできます。この場合、ソースとしてのプロバイダは必要ありません。

// DataSet にデータを格納します
DataSet ds = new DataSet();
FillDataSetFromHardwareDevice(ds);
// データを SqlServer にコピーします
string connect_string = GetConnectStringFromConfigFile();
SqlBulkCopy bcp = new SqlBulkCopy(connect_string);
bcp.DestinationTableName = "hardware_readings";
bcp.WriteToServer(ds);

プロバイダ統計

一部のアプリケーション開発者にとっては、アプリケーションで "リアルタイム" の監視が役立つ場合があります。 Windows パフォーマンス モニタを使用し、独自のパフォーマンス クラスを定義し、内部 (脆弱な場合があり、長時間にわたる) SQL Server メタデータ呼び出しを使用してこの情報を取得できましたが、現在、SqlClient は組み込みまれた方法でこの情報を提供します。 SqlConnection クラスのインスタンス メソッドを使用すると、ODBC API で使用できる統計と同様に、接続単位の統計を収集できます。 これらの統計の格納および収集には独自のオーバーヘッドがかかるため、統計の収集の切り替えに使用できるプロパティが用意されています。 カウンタをリセットするメソッドもあります。 もちろん、統計の収集は既定ではオフになっており、プールを行うシナリオで Dispose または Close を呼び出して接続プールに接続を戻したときもオフに設定されます。 生成される統計の例を次に示します。

string connect_string = GetConnectStringFromConfigFile();
SqlConnection conn = new SqlConnection(connect_string);
conn.Open();

// 有効化します
conn.StatisticsEnabled = true;

// いくつかの操作を実行します
//
SqlCommand cmd = new SqlCommand("select * from authors", conn);
SqlDataReader rdr = cmd.ExecuteReader();

Hashtable stats = (Hashtable)conn.RetrieveStatistics();

// stats を処理します
IDictionaryEnumerator e = stats.GetEnumerator();
while (e.MoveNext())
Console.WriteLine("{0} : {1}", e.Key, e.Value);

conn.ResetStatistics();


                    接続固有の統計
BuffersReceived   : 1
BuffersSent       : 1
BytesReceived     : 220
BytesSent         : 72
ConnectionTime    : 149
CursorFetchCount  : 0
CursorFetchTime   : 0
CursorOpens       : 0
CursorUsed        : 0
ExecutionTime     : 138
IduCount          : 0
IduRows           : 0
NetworkServerTime : 79
PreparedExecs     : 0
Prepares          : 0
SelectCount       : 0
SelectRows        : 0
ServerRoundtrips  : 1
SumResultSets     : 0
Transactions      : 0
UnpreparedExecs   : 1

これらの統計が正確には何を表しているかの詳細については、ADO.NET 2.0 または ODBC のドキュメントを参照してください。

AttachDbFileName

SqlClient データ プロバイダは、(ユーザーのデスクトップでデータベースを格納する) デスクトップ アプリケーション、クライアント サーバー アプリケーション、およびミドルウェアベースのアプリケーションをサポートします。 MSDE と呼ばれている SQL Server の特別なバージョンがあります。この製品の SQL Server 2005 年号名は SQL Server 2005 Express Edition です。 デスクトップ アプリケーションでは、データベース自体がアプリケーション固有のものであり、アプリケーションとバンドルされています。 アプリケーション セットアップ プログラムが SQL Server Express のインストールを実行するため、ユーザーは SQL Server がデータ リポジトリとして使用されていることに気付かない可能性すらあります。

アプリケーションの内部の SQL Server Express インスタンスにデータベース ファイルを添付できるように、ADO.NET 1.0 では、接続文字列パラメータ AttachDbFileName を提供していました。 このパラメータは、ハードコーディングされたパス名として指定する必要がありましたが、このため、ユーザーは既定以外の場所にアプリケーションをインストールしづらくなっていました。 ADO.NET 2.0 では、AttachDbFileName パラメータは、相対パスにすることができ、アプリケーションの構成設定と組み合わせて使用されます。 これによって、SQL Server Express に対するデスクトップ アプリケーションの設定が、Microsoft Access ファイルベースのデータ ストアへの接続と同じくらい簡単になります。

SqlClient における SQL Server 2005 固有の機能

MARS

SQL SELECT ステートメントを使用して、スタンドアロンとして、またはストアド プロシージャの内部に、行のセットを選択すると、SQL Server によって (一部のデータベースで行われるように) 自動的に行のセットの上にカーソルが作成されることはありません。 その代わり、ときどきネットワーク ライブラリによってデータがパケットサイズのチャンクとして抽出されると、データベース バッファから直接読み込みを行いながら、最適化されたメソッドを使用して結果セットをネットワーク経由でストリーム配信します。 これは、SQL Server Books Online では "SQL Sever の既定の結果セット" または "カーソルレス結果セット" として説明されています。 SQL Server 2005 より前の SQL Server のバージョンでは、単一の接続上に一度に存在することができるアクティブなカーソルレス結果セットは、1 つだけでした。

さまざまなデータベース API とライブラリは、1 つの接続または 1 つのカーソルレス結果セットの動作を個別に処理しました。 ADO.NET 1.0 と 1.1 では、別のカーソルレス結果セットを開こうとするとエラーがスローされます。従来の ADO では、実際に新しいデータベース接続が背後で開かれていました。 新しいデータベース接続を開いたほうが便利だったのですが、エラーをスローする場合に比べて緻密な正確さに欠けていました。この便利な機能は、一部のプログラマによって誤って濫用されていましたが、結果として予期していた数よりも多くのデータベース接続が発生していました。

SQL Server 2005 では、一度に複数のカーソルレス結果セットを単一の接続上でアクティブにすることが許可されるように、データベースが拡張されました。 これによって、"MARS" (複数のアクティブな結果セット) という略語が作られました。 この動作をサポートするネットワーク ライブラリに対する変更があり、MARS を有効にするには、新しいネットワーク ライブラリと新しいデータベースの両方が必要です。

SqlClient コードでは、複数の SqlCommand インスタンスが同じ接続を使用するように設定することによって、結果セットを多重化します。 各 SqlCommand は、Command.ExecuteReader を呼び出すことによって作成された SqlDataReader に対応でき、複数の SqlDataReader は連携して使用できます。 ADO.NET 1.0 および 1.1 では、複数の SqlCommand が使用されている場合でも、1 つの SqlDataReader を閉じてから別の SqlDataReader を取得する必要があります。 同じ SqlCommand インスタンス上で複数の ExecuteReader 呼び出しから作成された SqlDataReaders は、多重化できないことに注意してください。 簡単な (ただし、機能として非常に役立つ) 例を次に示します。

// 接続文字列はハードコーディングしないでください
string connstr = GetConnStringFromConfigFile();
SqlConnection conn = new SqlConnection(connstr);
SqlCommand cmd1 = new SqlCommand(
  "select * from employees", conn)
SqlCommand cmd2 = new SqlCommand(
  "select * from jobs", conn)
SqlDataReader rdr1 = cmd1.ExecuteReader();
// 次のステートメントは SQL Server 2005 より前のエラーを引き起こします
SqlDataReader rdr2 = cmd2.ExecuteReader();
// ここでは、同時に rdr1 と rdr2 から reader として指定できます。

この機能は、エラーを削減したり、ADO ライブラリの便利な機能を明確にしたりするためのものではありません。 これは、前に説明した非同期操作と組み合わせると非常に役立つことがあります。 複数の非同期 SELECT ステートメントまたはストアド プロシージャの呼び出しは、データベース接続を保存し、スループットを最適化しながら、連携して実行できるようになります。 1 つのフォーム上に、単一の接続を使用して同時に 20 個のドロップダウン リスト ボックスに値を設定する場合について考えてみましょう。 結果セットがアクティブな状態である間に non-resultset-returning ステートメントも実行できます。

実行の複数のストリームは同時にアクティブにできますが、トランザクションが存在する場合は、すべての実行ストリームは同じトランザクションを共有する必要があります。 トランザクションは、まだ、コマンドスコープというより接続スコープです。 SqlCommand Transaction プロパティを ADO.NET の以前のバージョンのように設定することにより、SqlTransaction インスタンスを SqlCommand に関連付けます。

SqlDependency と SqlNotificationRequest

別のユーザーがデータベース内の行を変更したという事実に基づいてキャッシュを更新できると、中間層キャッシュ状況では非常に役立ちます。 プログラマは、表またはビューが変更されるとファイルを更新するトリガを記述したり、データベースが変更されてもされなくてもときどきキャッシュを更新するなど、いくつかの異なる手法を使用してこれを実現します。 SqlClient SqlNotificationRequest クラスと SqlDependency クラスまでデータベース通知の登録を簡単に行う方法はありません。

SqlDependency は、SqlNotificationRequest をラップし、.NET イベントとして通知情報を表示する高レベルのクラスです。 SqlNotificationRequest を使用すると、イベントはありません。通知に対する登録とユーザー自身で情報を収集するという "負荷の高い作業" を行う必要があります。 大部分のプログラマは、SqlDependency を使用します。 SqlDependency は、スタンドアロンとして使用でき、その機能は ASP.NET Cache クラスを使用すると直接使用できます。

この SQL Server 2005 固有の機能は、スケーラブルなキュー システムを実装する新しい機能である SQL Server Service Broker に応じて異なります。 ASP.NET Cache クラスを使用する場合は、データベースのポーリングが Service Broker の代わりに使用され、同様の機能が実現されるということに注意してください。 Service Broker と SQL Server 2005 を使用すると、通知を受けるためにデータベースへの接続を維持する必要がありません。 SqlDependency は、ユーザーが選択した HTTP または TCP プロトコルを使用し、基盤となる行が変更されるとユーザーに連絡します。 通知には行固有の情報は含まれません。 通知を受けたら、行のセット全体を取得し、この通知に対して再登録する必要があります。

この機能は、単一のキャッシュまたは限定されたユーザーに対して必要なものですが、待機中の多くのユーザーに対して同時に使用する場合は注意してください。 各ユーザーは、任意の行が変更されるとキャッシュ内の行セット全体を更新する必要があります。 多くの変更がある場合、および多くのユーザーが対象の場合、更新のために使用する SELECT ステートメントによって、データベースに大きな影響が及ぶ可能性があります。

パスワードの変更

SQL Server 2005 は、ログイン (SQL Server に接続する Windows ログイン) を統合したその他のパスワード ポリシーと同じ有効期限に従って SQL ログインを使用するためのメカニズムを提供します。 この機能には、Windows Server 2003 上で実行されている SQL Server 2005 が必要です。SQL ログイン パスワード (sa など) の期限が切れた場合、従来の Windows メカニズムとパスワード変更 API を使用してパスワードを変更することはできなくなります。 最終的に Transact SQL ALTER LOGIN 動詞を呼び出すことになる SQL Server クライアントを使用した場合にだけ、このパスワードを変更できます。

SqlClient は、SqlConnection クラス上の ChangePassword メソッドを通してこれに対応します。 このメソッドは、SQL Server 2005 インスタンスに対して実行された場合にのみ使用できることに注意してください。古いバージョンのデータベースで SQL ログインを変更できますが、この API は、SQL Server のその他のバージョンがサポートしていないネットワーク パケット タイプを使用します。 パスワード変更に関連して考慮する必要がある別の側面は、プログラムの接続文字列に SQL Server ログイン ID とパスワードをハードコーディングできないという点です。 パスワードが変更されるたびに .NET 中間言語を作成して実行可能ファイルを置き換えなければ (これは実質的に実現不可能)、構成ファイル内に SQL Server パスワードを保存する必要があります。 真面目な SQL Server の開発者は、かなり前から構成ファイルを使用してパスワード (できれば暗号化されたもの) を保存してきました。 可能であれば、さらにセキュリティを向上させるために SQL Server の統合されたセキュリティを必ず使用します。

System.Transactions 統合

ADO.NET 2.0 の SqlClient プロバイダは、昇格可能なトランザクションと呼ばれる動作を有効にして、新しい System.Transactions 名前空間と統合されます。 Transact SQL を使用してローカル トランザクションまたは分散トランザクション (BEGIN TRANSACTION および BEGIN DISTRIBUTED TRANSACTION) を開始できますが、特にクライアント側または中間層プログラミングでは、プログラマが 1 つのデータベース シナリオまたは複数のデータベース シナリオで使用できるコンポーネントを作成したいと考える可能性があります。 これらのシナリオには、複数の SQL Server インスタンスが含まれる可能性があり、SQL Server は自動的にマルチインスタンス アクセスを検出し、トランザクションをローカルからマルチインスタンス (分散) に "昇格" できます。 これは、最初のデータベース (分散トランザクション用語ではリソース マネージャと呼ばれる) が SQL Server であれば、複数のデータベース製品または複数の接続が使用されている場合でも可能です。 昇格可能なトランザクションは、ADO.NET では既定で有効になっています。

クライアント フェールオーバー

SQL Server 2005 は、データベース ミラーリングを通して "ホット スペア" 機能をサポートしています。 SQL Server インスタンスが失敗した場合は、作業はバックアップ サーバーに自動的にシフトできます。 これには、(当然ながら) "証明インスタンス" と呼ばれるフェールオーバーを証明するインスタンスが必要です。 ホット スペア シナリオでは、既存クライアント接続がフェールオーバー (新しいサーバー インスタンスへの接続を確立) するには "知る" 必要がある、という条件があります。 次に試行されるアクセスでエラーを引き起こし、クライアント プログラミングによって手動で "フェールオーバー" する必要があるクライアント接続は、望ましくありません。 ADO.NET 2.0 内の SqlClient は、アプリケーション プログラムを特にプログラミングしなくてもクライアント フェールオーバーをサポートします。

新しいトランザクション分離レベルのサポート

SQL Server 2005 は、ロックとバージョン管理という 2 つの方法を使用してトランザクション分離をサポートします。 SQL Server の以前のバージョンは、ロックはサポートしていましたが、バージョン管理はサポートしていませんでした。 SQL Server 2005 では 2 種類のバージョン管理がサポートされます。これらはステートメントレベル バージョン管理とトランザクションレベル バージョン管理と呼ばれます。 この機能は、極端な環境で選択的にロックを削減し、データベースのバージョン管理のためにデザインされたアプリケーションの変換を簡単にできるようにします。 データベースのバージョン管理のためにデザインされたアプリケーションは、ロックしているデータベースにポーティングする場合に大幅な変更が必要になることがよくあります。 データベースのバージョン管理の既定の動作は、ほとんどいつもステートメントレベルのバージョン管理です。 差異の詳細については、Beauchemin、Berglund、および Sullivan による「A First Look at SQL Server 2005 for Developers (英語)」を参照してください。

さまざまなバージョン管理とさまざまなロックの動作の両方は、特定のトランザクション分離レベルを使用したトランザクションの開始に対しては同等です。 ANSI SQL 仕様によって定義された 4 つのトランザクション分離レベルがあります。

  • READ UNCOMMITED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

SQL Server は 4 つの分離レベルのすべてをサポートし、SQL Server 2005 より前でも同様にサポートしていました。バージョン管理データベースは、通常、READ COMMITTED と SERIALIZABLE のみをサポートします。 READ COMMITTED はステートメントレベルのバージョン管理を実装し、SERIALIZABLE はバージョン管理データベースでトランザクションレベルのバージョン管理を実装します。 READ COMMITTED は、ロックまたはバージョン管理が使用されるほとんどすべてのデータベースの既定の動作です。

ステートメントレベルのバージョン管理が有効になっており、これは、データベースごとにデータベース オプションを設定することによって、既定の動作になっています。 ステートメント バージョン管理が有効になっている場合に、IsolationLevel.ReadCommitted または IsolationLevel.ReadUncommitted を指定すると、この動作が使用されます。 トランザクションレベルの分離をサポートするには、SQL Server 2005 によって新しい分離レベル IsolationLevel.Snapshot が定義されます。 SqlClient (SqlClient のみ) がこの分離レベルをサポートします。 ユーザーがステートメントレベル、またはトランザクションレベルのバージョン管理を個別にオンにでき、IsolationLevel.Serializable がロック動作に対応するために SQL Server によって既に使用されているため、この分離レベルが要求されました。

DataTypes - UDT、XML データ型、"MAX" BLOB および CLOB

SQL Server 2005 によって、ユーザー定義の型に対するサポート、ネイティブ XML データ型、および大きなデータ サポートの強化が追加されます。 大きなデータのサポートは、Transact-SQL 型である VARCHAR (MAX)、NVARCHAR (MAX)、および VARBINARY (MAX) を使用しすることによって、強化されます。 ユーザー定義の型とネイティブ XML 型は、SQL:1999 と SQL:2003 の各仕様によって定義されます。 SqlClient でこれらのデータ型を使用するために、System.Data.SqlTypes 名前空間で新しいクラスが定義され (SqlUdt および SqlXml)、サポートが SqlDbTypes 列挙に追加されます。また、IDataReader.GetValue が拡張されて UDT を .NET オブジェクト型として返すことがサポートされ、XML を .NET 文字列として返すことがサポートされます。

これらの新しい SQL Server 2005 の型は、SQL SELECT ステートメントから返される DataReaders で、SqlParameter を使用してパラメータとしてサポートされます。 特別なクラスである SqlMetaData は、厳密に型指定された XML 列が準拠する XML スキーマ コレクションや UDT のデータベース名など、これらの新しいデータ型の拡張されたプロパティに関する情報を返すことができます。 これらの型は、汎用コードにおいて、また DataSet でも、クライアントから直接使用できます。 最後に、クライアントから "MAX" データ型に関する部分更新を実行できます。これには、ADO.NET 2.0 の前に特別な SQL 関数を使用する必要があります。 詳細については、このサイトの将来の記事で説明します。

まとめ

さて、 多くの機能があり、把握するには多すぎるくらいです。 新しい機能の海でおぼれないようにするため、最後に各新機能と、それを動作させるために必要なデータベース、プロバイダ、およびバージョンの表を用意しました。 現在は、ADO.NET の一部である 4 つのプロバイダに関する情報しかありませんが、その他のプロバイダ ベンダも間もなく参加するでしょう。 将来の記事では、この表がさらに拡張されていることを願っています。

新しい機能の利用可能性

  すべてのプロバイダ SQL Server 7/2000 SQL Server 2005
プロバイダ ファクトリ X X X
部分信頼コードを使用した実行 X X X
サーバー列挙 X X X
接続文字列ビルダ X X X
メタデータ スキーマ X X X
バッチ更新のサポート X X X
プロバイダ固有の型 X X X
競合の検出 X X X
トレースのサポート X X X
プールの機能拡張 SqlClient および OracleClient X X
MARS     X
SqlNoticicationRequest     X
SqlDependency     X
IsolationLevel.Snapshot     X
非同期コマンド X X X
クライアント フェールオーバー     X
一括インポート X X X
パスワード変更 API     X
統計 X X X
新しいデータ型     X
昇格可能トランザクション   X X
AttachDbFileName   X X

Bob Beauchemin 氏は、DevelopMentor の教官、学習コースの作成者、およびデータベース カリキュラム コースの連絡係です。 データ中心の分散システムのアーキテクト、プログラマ、および管理者としての 25 年を超える経験を持っています。 Microsoft Systems Journal、SQL Server Magazine、およびその他のものに ADO.NET、OLE DB、SQL Server に関する記事を執筆したことがあり、書籍『A First Look at SQL Server 2005 for Developers (英語)』と『Essential ADO.NET (英語)』の著者でもあります。