ヘッダーをスキップ
Oracle Data Provider for .NET開発者ガイド
11gリリース1(11.1.0.6.20)
E06104-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

ADO.NET 2.0の機能

Oracle Data Provider for .NET 10.2.0.2以降は、Microsoft ADO.NET 2.0 APIをサポートします。

この項の内容は次のとおりです。

ADO.NET 2.0について

ADO.NET 2.0はMicrosoft社仕様であり、プロバイダの主体性、コンポーネントの再利用拡大およびアプリケーションの互換性に対して、共同で作業するために設計されたデータ・アクセス機能を提供します。追加の機能により、アプリケーションでデータ・ソース、スキーマおよびプロバイダに関する情報の動的な検索が簡単にできます。


注意:

Microsoft ADO.NET 2.0とともにODP.NETを使用するには、ADO.NET 2.0準拠のODP.NETが必要です。


関連項目:

MSDNライブラリ内のADO.NET


ADO.NETの下位互換性

プロバイダ主体の汎用データ・アクセス・コードを記述するため、ADO.NET 1.xはインタフェースを使用します。同じ目的で、ADO.NET 2.0は、下位互換性のためADO.NET 1.xからのインタフェースを保持しながら、継承ベースのアプローチも提供します。

ODP.NET for ADO.NET 2.0では下位互換性がサポートされているため、ADO.NET 1.x APIsも使用できます。

このガイドでは、適切な場合はADO.NET 2.0およびADO.NET 1.x両方に対する宣言も提供します。

ベース・クラスおよびプロバイダ・ファクトリ・クラス

ADO.NET 2.0では、データ・クラスはSystem.Data.Commonネームスペースで定義されたベース・クラスから導出されます。開発者は、プロバイダ・ファクトリ・クラスを使用して、これらのベース・クラスのプロバイダ固有のインスタンスを作成できます。

プロバイダ・ファクトリ・クラスでは、汎用データ・アクセス・コードによって、最小限のデータ・ソース固有コードで複数のデータ・ソースへアクセスできます。これにより、複数のデータ・ソースにアクセスするアプリケーションで現在使用されている条件付きロジックの多くを削減できます。

Oracle Data Provider for .NETを使用すると、OracleClientFactoryクラスを戻し、インスタンス化できます。これにより、ベース・クラスを継承する次のODP.NETクラスのインスタンスを作成するアプリケーションが有効になります。

表3-3 ADO.NET 2.0ベース・クラスを継承するODP.NETクラス

ODP.NETクラス ADO.NET 2.0ベース・クラスから継承

OracleClientFactory

DbProviderFactory

OracleCommand

DbCommand

OracleCommandBuilder

DbCommandBuilder

OracleConnection

DbConnection

OracleConnectionStringBuilder

DbConnectionStringBuilder

OracleDataAdapter

DbDataAdapter

OracleDataReader

DbDataReader

OracleDataSourceEnumerator

DbDataSourceEnumerator

OracleException

DbException

OracleParameter

DbParameter

OracleParameterCollection

DbParameterCollection

OracleTransaction

DbTransaction


一般に、アプリケーションはいまだOracle固有の接続文字列、SQLまたはストアド・プロシージャ・コールを必要としており、Oracle.DataAccess.Clientからのファクトリを使用することを宣言します。

接続文字列ビルダー

OracleConnectionStringBuilderクラスでは、エラーを起こしにくく、管理しやすい接続文字列を作成します。

このクラスを使用することによって、開発者は設定ファイルを使用した接続文字列の提供およびキー/値ペアによる動的な値の設定が可能です。設定ファイル・エントリの例は次のとおりです。

<configuration>
   <connectionStrings> 
<add name="Publications" providerName="Oracle.DataAccess.Client" 
           connectionString="User Id=scott;Password=tiger;Data Source=inst1" />
   </connectionStrings> 
</configuration>

接続文字列情報は、接続文字列名を指定して取得できます。この例ではPublicationsです。次に、providerNameに基づいて、そのプロバイダ用の適切なファクトリを取得できます。これにより、接続文字列を簡単に管理および変更できます。さらに、これによって接続文字列への文字列注入に対してより優れたセキュリティを提供します。

データ・ソース列挙子

データ・ソース列挙子では、アプリケーションによって、そのアプリケーションが接続できるOracleデータ・ソースのコレクションを一般的に取得できます。

スキーマ検出のサポート

ADO.NET 2.0では、OracleConnection.GetSchema APIから5つの異なるタイプのメタデータ・コレクションが公開されています。これにより、アプリケーション開発者は、すべてのOracleデータ・ソースに対して、メタデータの取得を個別のアプリケーション・ベースでカスタマイズできます。このようにして、開発者は複数のデータ・ソースからのメタデータを管理する汎用セットのコードをビルドできます。

公開されているメタデータのタイプは次のとおりです。

  • MetaDataCollections

    テーブル、列、インデックスおよびストアド・プロシージャなどのデータ・ソースから使用できるメタデータ・コレクションのリストです。

  • Restrictions

    要求されたスキーマ情報の範囲を制限して、各メタデータ・コレクションに適用される制限。

  • DataSourceInformation

    製品名やバージョンなど、現在使用されているデータベースのインスタンスについての情報。

  • DataTypes

    データベースがサポートする各データ型についての情報のセット。

  • ReservedWords

    Oracle問合せ言語の予約語。

メタデータのユーザー・カスタマイズ

ODP.NETでは、データベース・スキーマ情報の包括的なセットが提供されています。開発者は、個々のアプリケーション・ベースでGetSchemaメソッドが戻すメタデータを拡張またはカスタマイズできます。

これを行うには、開発者はカスタマイズしたメタデータ・ファイルを作成し、アプリケーションにファイル名を提供する必要があります。方法は次のとおりです。

  1. カスタマイズしたメタデータ・ファイルを作成し、それを.NET FrameworkがインストールされたCONFIGサブディレクトリに置きます。これは、machine.configおよびセキュリティ設定があるディレクトリです。

    このファイルには、変更のみではなく、スキーマ設定情報のセット全体を含める必要があります。開発者は、ユーザー固有の要件を検索するスキーマ動作の変更を提供します。たとえば、開発者は内部データベース表にフィルタをかけ、ユーザー固有の表のみを検索できます。

  2. 次と同じく、アプリケーションのapp.configファイル内にエントリを追加し、メタデータ・ファイルの名前を名前/値ペアの書式で指定します。

    <oracle.dataaccess.client>
      <settings>
        <add name="MetaDataXml" value="CustomMetaData.xml" />
      </settings>
    </oracle.dataaccess.client>
    

GetSchemaメソッドがコールされると、ODP.NETではapp.configファイルでカスタマイズしたメタデータXMLファイルの名前を確認します。最初に、GetSchemaメソッドはプロバイダにちなんで付けられた要素、この例ではoracle.dataaccess.clientでファイル内のエントリを検索します。このXML要素内の名前MetaDataXmlに対応する値は、カスタマイズしたXMLファイルの名前で、この例ではCustomMetaData.xmlです。

メタデータ・ファイルが正しいディレクトリ内にない場合、アプリケーションは、ODP.NETに含まれているデフォルトのメタデータXMLファイルをロードします。


関連項目:

GetSchema

System.Transactionsのサポート

ODP.NET for .NET Framework 2.0は、System.Transactionsをサポートします。System.Transactionsが使用されると、トランザクションは、「System.Transactionsサポートのローカル・トランザクション」で説明されているように、ローカル・トランザクションとして作成されるように指定されている場合を除き、(デフォルトで)すぐに分散トランザクションになります。

アプリケーションがSystem.Transactionsを使用する場合は、"enlist"接続文字列属性を"true"(デフォルト)または"dynamic"のいずれかに設定する必要があります。

ODP.NETは、分散トランザクションを使用するアプリケーション用に、次のSystem.Transactionsプログラミング・モデルをサポートしています。

TransactionScopeを使用した暗黙的な分散トランザクション登録

TransactionScopeクラスでは、分散トランザクションに明示的に登録する必要のないトランザクション・アプリケーションを記述する方法が提供されます。これを行うには、アプリケーションでTransactionScopeオブジェクトを使用して、トランザクション・コードを定義します。このトランザクション範囲内で作成された接続は分散トランザクションに登録されます。変更をコミットするには、アプリケーションでTransactionScopeオブジェクトに対してCompleteメソッドをコールする必要があります。コールしない場合、トランザクションはデフォルトで強制終了します。

// C#
 
using System;
using Oracle.DataAccess.Client;
using System.Data;
using System.Data.Common;
using System.Transactions;
 
class psfTxnScope
{
  static void Main()
  {
    int retVal = 0;
    string providerName = "Oracle.DataAccess.Client";
    string constr = 
           @"User Id=scott;Password=tiger;Data Source=oracle;enlist=true";
 
    // Get the provider factory.
    DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
 
    try
    {
      // Create a TransactionScope object, (It will start an ambient
      // transaction automatically).
      using (TransactionScope scope = new TransactionScope())
      {
        // Create first connection object.
        using (DbConnection conn1 = factory.CreateConnection())
        {
          // Set connection string and open the connection. this connection 
          // will be automatically enlisted in a distributed transaction.
          conn1.ConnectionString = constr;
          conn1.Open();
 
          // Create a command to execute the sql statement.
          DbCommand  cmd1 = factory.CreateCommand();
          cmd1.Connection = conn1;
          cmd1.CommandText = @"insert into emp (empno, ename, job) values 
                                                     (1234, 'emp1', 'dev1')";
 
          // Execute the SQL statement to insert one row in DB.
          retVal = cmd1.ExecuteNonQuery();
          Console.WriteLine("Rows to be affected by cmd1: {0}", retVal);
 
          // Close the connection and dispose the command object.
          conn1.Close();
          conn1.Dispose();
          cmd1.Dispose();
        }
 
        // The Complete method commits the transaction. If an exception has
        // been thrown or Complete is not called then the transaction is 
        // rolled back.
        scope.Complete();
      }
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.Message);
      Console.WriteLine(ex.StackTrace);
    }
  }
}

CommittableTransactionを使用した明示的な分散トランザクション登録

CommittableTransactionオブジェクトとEnlistTransactionメソッドのインスタンス化によって、接続を明示的に作成して分散トランザクションに登録できます。アプリケーションでは、CommittableTransactionオブジェクトに対してCommitまたはRollbackをコールする必要があります。

// C#
 
using System;
using Oracle.DataAccess.Client;
using System.Data;
using System.Data.Common;
using System.Transactions;
 
class psfEnlistTransaction
{
  static void Main()
  {
    int retVal = 0;
    string providerName = "Oracle.DataAccess.Client";
    string constr = 
           @"User Id=scott;Password=tiger;Data Source=oracle;enlist=dynamic";
 
    // Get the provider factory.
    DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
 
    try
    {
      // Create a committable transaction object.
      CommittableTransaction cmtTx = new CommittableTransaction();
 
      // Open a connection to the DB.
      DbConnection conn1 = factory.CreateConnection();
      conn1.ConnectionString = constr;
      conn1.Open();
 
      // enlist the connection with the commitable transaction.
      conn1.EnlistTransaction(cmtTx);
 
      // Create a command to execute the sql statement.
      DbCommand cmd1 = factory.CreateCommand();
      cmd1.Connection = conn1;
      cmd1.CommandText = @"insert into emp (empno, ename, job) values 
                                                     (1234, 'emp1', 'dev1')";
 
      // Execute the SQL statement to insert one row in DB.
      retVal = cmd1.ExecuteNonQuery();
      Console.WriteLine("Rows to be affected by cmd1: {0}", retVal);
 
      // commit/rollback the transaction.
      cmtTx.Commit();   // commits the txn.
      //cmtTx.Rollback(); // rolls back the txn.
 
      // close and dispose the connection
      conn1.Close();
      conn1.Dispose();
      cmd1.Dispose();
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.Message);
      Console.WriteLine(ex.StackTrace);
    }
  }
}

関連項目:

EnlistTransaction

System.Transactionsサポートのローカル・トランザクション

Oracle Data Provider for .NETリリース10.2.0.3以降のアプリケーションは、System.Transactionsとともにローカル・トランザクションを使用できます。ODP.NETの以前のバージョンでは、System.Transactionsを使用した分散トランザクションのみサポートされていました。

ローカル・トランザクションを使用するには、PromotableTransactionレジストリ・エントリを作成して"local"に設定するか、"Promotable Transaction"接続文字列属性を"local"に設定する必要があります。

"local"が指定されている場合、TransactionScopeでオープンした最初の接続ではローカル・トランザクションが使用されます。後続の接続が同じTransactionScopeでオープンされると例外がスローされます。TransactionScopeですでに接続がオープンしていて、"Promotable Transaction=local"OracleConnectionが同じTransactionScope内でオープンされようとしている場合は例外がスローされます。

"promotable"が指定されている場合、同じTransactionScopeでオープンされる最初と後続の接続は、同じ分散トランザクション内で登録されます。

レジストリと接続文字列属性の両方が使用されていて異なる値に設定されている場合、接続文字列属性はレジストリ・エントリの値をオーバーライドします。どちらも設定されていない場合は"promotable"が使用されます。これはデフォルトの値で、分散トランザクションのみがサポートされているODP.NETの以前のバージョンと同じです。

ODP.NETの特定のバージョンに対するレジストリ・エントリは、ODP.NETのバージョンを使用するすべてのアプリケーションに適用します。

バッチ処理のサポート

OracleDataAdapter.Updateメソッドがコールされると、OracleDataAdapter UpdateBatchSizeプロパティではバッチ処理が有効になります。UpdateBatchSizeは、各ラウンドトリップで、Oracleデータベースを更新するDataSet行数を示す数値プロパティです。

これにより、開発者はデータベースへのラウンド・トリップの回数を削減できます。


注意:

Microsoft社の必要なホットフィックス

Microsoft ADO.NET 2.0にはBatchUpdate機能に影響する既知の問題があります。

この問題を解決するには、ODP.NETリリース11.1とMicrosoft社の特定のホットフィックスの両方を同じコンピュータにインストールする必要があります。Microsoft社のホットフィックスは、http://support.microsoft.com/?id=916002から無料ダウンロードできます。

このフィックスがないと、BatchUpdate機能はDataSetで失敗した行に関するエラーの正しい説明を表示しません。DbDataDataAdapter.ContinueUpdateOnErrorfalseであるか、DataSetの最終更新行のRowErrorプロパティに追加されている場合は、バッチ内のすべてのエラーは例外メッセージに追加されています。

ODP.NETは、このホットフィックスを使用して、バッチ内で失敗した個々の行のRowErrorプロパティに対してエラーの正しい説明を作成するよう拡張されています。



関連項目:

UpdateBatchSize

ADO.NET 2.0専用クラスおよびクラス・メンバー

ADO.NET 2.0専用であるクラスに加えて、System.Data.Commonネームスペースから継承する他のODP.NETクラスには、ADO.NET 2.0を必要とするメソッドとプロパティが含まれています。

次のクラスはADO.NET 2.0専用です。

次のクラス・メンバーはADO.NET 2.0専用です。

一括コピー・サポート

ODP.NETは、アプリケーションが1つのデータベースの表から同一または異なるデータベースの表へ大量のデータを効率よくロードできる一括コピー機能を提供します。

ODP.NETの一括コピー機能では、ダイレクト・パス・ロード方法を使用します(これはOracle SQL*Loaderと類似していますが異なります)。ダイレクト・パス・ロードを使用すると、Oracleのデータ・ブロックをフォーマットしてデータ・ファイルに直接データ・ブロックを書き込むため、SQL INSERT文を使用する従来のロードより早く処理できます。これにより処理中のオーバーヘッドが大幅に削減されます。

ODP.NETの一括コピー機能では、9iリリース2、10gリリース1、10gリリース2および11gリリース1データベースにデータをロードできます。

ODP.NETの一括コピー機能は、次の項で説明するように、ダイレクト・パス・ロードと同一の基本制限および整合性制約に従います。

単一パーティションのOracle一括コピーの制限

  • パーティションを含む表には、表で定義済のグローバル索引を含めることはできません。

  • パーティションがメンバーの表には、有効な参照制約およびチェック制約を含めることはできません。

  • 有効なトリガーは使用できません。

Oracle一括コピーに影響する整合性制約

Oracle一括コピー中、次の場合にいくつかの整合性制約は自動的に有効または無効になります。

有効となる制約

Oracle一括コピー中、次の制約はデフォルトで自動的に有効になります。

  • NOT NULL

  • UNIQUE

  • PRIMARY KEY(非NULL列での一意制約)

NOT NULL制約は列配列の作成時にチェックされます。NOT NULL制約に違反する行はすべて拒否されます。

UNIQUE制約はロードの最後で索引が再構築されるときに検証されます。この索引はUNIQUE制約に違反すると、索引使用禁止状態のままになります。

無効となる制約

Oracle一括コピー中、次の制約はデフォルトで自動的に無効になります。

  • CHECK制約

  • 参照制約(FOREIGN KEY

EVALUATE CHECK_CONSTRAINTS句を指定する場合、CHECK制約は自動的には無効になりません。CHECK制約はダイレクト・パス・ロード中に評価され、CHECK制約に違反する行はすべて拒否されます。

データベース挿入トリガー

ダイレクト・パス・ロードが始まると、表挿入トリガーも使用禁止になります。行がロードされ索引が再構築されると、使用禁止となっていたすべてのトリガーは自動的に再び使用可能になります。ログ・ファイルには、ロード時に使用禁止となっていたトリガーがすべてリストされます。トリガーを使用可能に戻すときに1つでもエラーがあると、再使用できません。

整合性制約とは異なり、挿入トリガーは使用可能に戻っても表全体に対して再び適用されません。つまり、ダイレクト・パスでロードされた行に対しては、挿入トリガーは起動しません。ダイレクト・パスを使用する際には、挿入トリガーに関連するすべての動作が新しい行に対して実行されることを確認する必要があります。

フィールドのデフォルト値

データベースで定義されたデフォルト列の仕様はダイレクト・パス・ロードを使用できません。デフォルト値が必要なフィールドはDEFAULTIF句で指定する必要があります。DEFAULTIF句を指定せず、フィールドがNULLの場合、NULL値がデータベースに挿入されます。