.NETへの快適なドライブ
Christian Shay著
簡単にデプロイできるコンパクトなOracle Data Provider for .NET管理対象ドライバを利用する
Oracle Data Provider for .NET(ODP.NET)はオラクルが無料で提供する、ADO.NETに準拠した高パフォーマンスのデータ・アクセス・プロバイダです。.NET開発者は、C#やVB.NETなどの.NET言語を利用してOracle Databaseのすべての機能にアクセスできるようになります。またODP.NETは、ADO.NETや.NET Frameworkのすべての機能(Entity Frameworkオブジェクト・リレーショナル・マッパーなど)をサポートしています。
現在、ODP.NETには2種類のドライバがあります。1つは、ODP.NET管理対象外ドライバです。このドライバには管理対象外(unmanaged)コードが含まれます。つまり、このドライバが依存するライブラリの一部は、.NETバイトコードではなく、直接マシン・コードへとコンパイルされています。ODP.NET 12.1では、もう1つのODP.NET管理対象ドライバが導入されました。このドライバは完全に管理されています。つまり、ドライバ全体、およびドライバを補助するクライアント・ライブラリとネットワーク・ライブラリが.NETバイトコードにコンパイルされており、そのすべてが共通言語ランタイム(.NETの仮想マシン)の内部で実行されます。Javaの知識がある人にとっては、ODP.NET管理対象外ドライバを“Thick” JDBCに、ODP.NET管理対象ドライバを“Thin” JDBCにたとえると分かりやすいでしょう。
ODP.NET管理対象ドライバの特徴のうち、特に魅力的なのがサイズです。このドライバはわずか2つのダイナミック・リンク・ライブラリ(DLL)で構成され、利用するディスク領域は合計で10MB未満です。このドライバには必要になる機能がすべて含まれており、その他のOracleクライアントやネットワーク・ライブラリは不要です。そのため、デプロイ作業が非常に単純になり、ClickOnce配置やWeb配置などのMicrosoftのデプロイメント技術を簡単に利用できます。異なるバージョンのODP.NETを並行してデプロイすることも簡単であり、多くの場合、デプロイのターゲットが32ビットか64ビットかを考慮する必要がなくなります。
この記事では、ODP.NET管理対象ドライバのダウンロードとインストールの方法を説明し、ネットワークの構成方法を示します。その後、管理対象外から管理対象への移行例を段階的に説明します。さらに、分散トランザクションを有効にするための要件について説明します。説明の過程で、はじめて利用するユーザーが陥りやすい、いくつかの“罠”について注意を喚起します。
この記事では、Microsoft Visual Studio 2012を使用します。説明の手順を実行するには、Visual Studio 2010以降が必要になります。また、Oracle Developer Tools for Visual Studio(ODTとも呼ばれる)をインストールしますが、このツールではVisual Studio Expressがサポートされません。Visual Studio Expressを使用している場合、この説明のうち、サーバー エクスプローラー(Visual Studioのサーバー管理コンソール)での接続、およびTableAdapterとデータセットの生成に関わる部分は実行できません。
また、Oracle Database 10g Release 2(10.2)以降にアクセスし、HRサンプル・スキーマにアクセスする必要もあります。Oracle Databaseはこちらからダウンロードできます(HRスキーマは基本インストール・オプションに含まれていますが、Oracle DatabaseサンプルをインストールしてHR作成スクリプトを実行することで、HRスキーマを手動で作成することもできます)。さらに、ODP.NET管理対象ドライバでは.NET Framework 4以降が必要になります。
ODP.NET管理対象ドライバは、Oracle Technology Network Webサイトにある複数の無料ダウンロード・ファイルに含まれています。このドライバはOracle Data Access Components 12.1以降の一部として提供されます。Oracle Data Access ComponentsではOracle Data Provider for .NETとして表記され、管理対象外と管理対象の両方のODP.NETが含まれています。Oracle Data Access Components(ユーザー・インタフェース内ではODACと呼ばれる)はOracle Universal Installerによって、xcopyインストールとしてパッケージ化されています。このxcopyインストールは、Oracle Data Access Componentsのコピーと構成に使用される一連のファイルと一部のバッチ・ファイルがzip形式で圧縮されたものです(ODP.NET管理対象ドライバは、非常に小さなxcopyインストールとして単体でも配布されています)。
Visual Studioを使用して設計作業を行う場合、たとえば、ADO.NET Entity Data Modelデザイナー(Entityデザイナー)を利用したり、TableAdapterやデータセットを作成したりする場合は、Oracle Developer Tools for Visual Studioも必要になります。
まずは、Oracle Developer Tools for Visual Studio with Oracle Data Access Componentsをダウンロードします。これは、32ビットのOracle Data Access ComponentsとOracle Developer Tools for Visual Studioを含むソフトウェア・バンドルです(Visual Studioは32ビット・アプリケーションです)。Oracle .NET Developer Centerにアクセスして、ページ上部の「Download」タブをクリックします。「32-bit ODAC with ODT Downloads」をクリックし、表示される最新バージョンのODTwithODAC…zip(Release 12.1以降)を選択します。このファイルを一時ディレクトリ内に解凍し、その解凍先のsetup.exeを実行します。
ODT with ODACインストール・パッケージではOracle Universal Installerが使用されます。このインストーラのWelcome画面が表示されたら、「Next」をクリックし、次の画面のNameフィールドにOracleホームの名前を入力し、PathフィールドにOracleホームのパスを入力して、「Next」をクリックします。デフォルトでは、これらのフィールドには、提示される新しいOracleホームの名前とパスが自動的に入力されます(一般的には、新しいバージョンのOracleソフトウェアは新しいOracleホームにインストールすることをお勧めします)。
次の画面に、インストール可能な製品コンポーネントのリストが表示されます。Oracle Data Provider for .NET、Oracle Developer Tools for Visual Studio、Oracle Data Access Components Documentation for Visual Studio、Oracle Instant Clientを除くすべての項目を選択解除し、「Next」をクリックします。環境によっては、Database Connection Configuration画面が表示される場合があります。表示された場合は、必要に応じてデータベースの接続詳細情報を入力し、「Next」をクリックします。また、統合するVisual Studioのバージョンを選択するように求められた場合は、バージョンを選択して「Next」をクリックします。最後に、Installation Summary画面で「Install」をクリックし、インストールを開始します。数分後にインストールが完了したら、インストーラを閉じてください。
管理対象外のODP.NETを扱った経験のある開発者にとっては、管理対象外ドライバと管理対象ドライバの違いを理解する上で最適な方法はおそらく、この2つの間で移行作業を実施することでしょう。そのためには、ODP.NET管理対象外ドライバを使用する、実際に動作するアプリケーションが必要になります。
download.zip(サンプル・コードのファイル)をダウンロードします。このファイルを一時ディレクトリに抽出します。
次に、Visual Studioで新しいWinformプロジェクトを作成します。そのためには、Visual Studioを起動し、「ファイル」→「新規作成」→「プロジェクト」→「Windowsフォーム アプリケーション」を選択します。ツールボックスのコモン コントロール・セクションからボタンをドラッグします。そのボタンをダブルクリックして、内部のコードにアクセスします。button_Click()ハンドラに、button_click.txtファイル(抽出済みのdownload.zipファイルに含まれるファイル)のコードを追加します(参考用に、このコードをリスト1にも示します)。接続文字列のデータソースに対してデータベースの正確なホスト名、ポート、サービス名を指定するようにコードを変更します。この情報は、このデータベースへの接続に使用しているTNSNAMES.ORAファイルにあります。
コード・リスト1:button_Click()ハンドラのコード
string conString = "User Id=hr; password=hr;" +
//EZ Connect Format is [hostname]:[port]/[service_name]
//Examine working TNSNAMES.ORA entries to find these values
"Data Source=localhost:1521/pdborcl; Pooling=false;";
//Create a connection to Oracle
OracleConnection con = new OracleConnection();
con.ConnectionString = conString;
con.Open();
//Create a command within the context of the connection
//Use the command to display employee names and salary from Employees table
OracleCommand cmd = con.CreateCommand();
cmd.CommandText = "select first_name from employees where department_id = 60";
//Execute the command and use datareader to display the data
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
MessageBox.Show("Employee Name:" + reader.GetString(0));
}
ソリューション エクスプローラーのプロジェクトの下にある「参照設定」を右クリックし、「参照の追加」を選択します。ダイアログ・ボックスで、「アセンブリ」をクリックし、Oracle.DataAccessアセンブリ(Version 4.x)を探します。複数の参照が存在する場合は、選択項目にマウスを合わせてパスを表示し、この参照が先ほどインストールしたODP.NETおよびOracle Developer Tools for Visual Studioを含むOracleホーム内に位置していることを確認します。「Oracle.DataAccess」を選択して「OK」をクリックします。button_Click()ハンドラを含むコード・ウィンドウに戻り、次のusing句のコードを最上部に追加します。
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
アプリケーションをビルドして実行します([F5]キーを押すか、「デバッグ」→「開始」を選択します)。次に、アプリケーションのボタンをクリックして、このボタン・ハンドラのコードによりOracle DatabaseのサンプルHRスキーマ内にあるEMPLOYEES表のデータが取得されて画面上に表示されることを確認します。
次に、DataGridView内にデータを表示するためのTableAdapterおよびデータセットを自動生成します。自動コード生成機能(TableAdapterやEntity Frameworkなどを利用)では、サーバー エクスプローラーのデータベース接続セットが使用されます(自動生成コード内で管理対象外のODP.NETを使用するようにアプリケーションを構成する場合は、サーバー エクスプローラーでODP.NET管理対象外ドライバを使用して接続します)。逆に、管理対象のODP.NETを使用するようにアプリケーションを構成する場合は、サーバー エクスプローラーでODP.NET管理対象ドライバを使用して接続する必要があります。
そのため、サーバー エクスプローラーでOracle Databaseへの接続を作成します。「表示」→「サーバー エクスプローラー」を選択し、「データ接続」を右クリックして「接続の追加」を選択します。接続の追加ダイアログ・ボックスでデータ ソースフィールドの「変更」をクリックします。データ ソースの変更ダイアログ・ボックスで、データ ソースとして「Oracle Database」を選択し、データ プロバイダーとして「ODP.NET, Unmanaged Driver」を選択します(図1を参照)。
図1:サーバー エクスプローラーの接続の追加ダイアログ・ボックスでのデータソースの変更
「OK」をクリックします。接続の追加ダイアログ・ボックスで、ユーザー名とパスワードを入力し、接続の種類として「EZ Connect」を選択します。次に、データベースのホスト名、ポート番号、データベース・サービス名を入力します(図2を参照)。「テスト接続」をクリックして接続のテストを行い、接続に成功したら「OK」をクリックします。
図2:接続の追加ダイアログ・ボックス
次に、ツールボックスに戻り、データ・セクションで「DataGridView」をフォーム・デザイン・サーフェイスにドラッグします。DataGridViewタスクのメニューで、「データ ソースの選択」をクリックし、「プロジェクト データソースの追加」リンクをクリックします。その後のダイアログ・ボックスで、データ ソースの種類として「データベース」を選択し、データベース モデルとして「データセット」を選択し、データ接続の選択では先ほど作成したサーバー エクスプローラーの接続を選択します。接続文字列にパスワードを含めるかという項目に対して「はい」、アプリケーション構成ファイル内に接続文字列を保存するかという項目に対して「はい」を選択します。データベース オブジェクト・ダイアログ・ボックスで、「テーブル」をドリルダウンし、「EMPLOYEES」表を選択します。
アプリケーションをビルドして実行すると、EMPLOYEES表のデータがDataGridViewに表示されます。
ODP.NET管理対象外ドライバに基づいたコードを管理対象ドライバに移行することは比較的簡単です。おもなタスクは次のとおりです。
コード内のusing句を変更する。
プロジェクト内の参照を、ODP.NET管理対象ドライバを使用するように置き換える。
TableAdapterとEntity Modelを、管理対象ドライバを使用するように編集する。
アプリケーションで使用されているOracle Databaseの機能が管理対象ドライバでサポートされていることを確認する。
ODP.NET管理対象外ドライバに基づいて作成したサンプルのWinformアプリケーションを移行して、代わりにODP.NET管理対象ドライバを使用するには、ソリューション エクスプローラーのプロジェクト参照設定の下にある「Oracle.DataAccess」をクリックし、[Delete]キーを押して削除します。
次に、「参照設定」を右クリックし、「参照の追加」を選択します。ダイアログ・ボックスで、「アセンブリ」をクリックし、Oracle.ManagedDataAccessアセンブリ(Version 4.x)を探します。複数の参照が存在する場合は、選択項目にマウスを合わせてパスを表示し、この参照が先ほどインストールしたODP.NETおよびOracle Developer Tools for Visual Studioの位置にあることを確認します。「Oracle.ManagedDataAccess」を選択して「OK」をクリックします。先ほど編集したbutton_Click()ハンドラのコードを含むコード・ウィンドウで、Oracle.DataAccess.ClientとOracle.DataAccess.Typesを参照している2つのusing句を次のように置き換えます。
using Oracle.ManagedDataAccess.Client;
using Oracle.ManagedDataAccess.Types;
図3に、更新後のusingディレクティブとプロジェクト参照を示します。
図3:コード内(左)でのusingディレクティブの設定と、プロジェクト参照設定(右)でのODP.NET管理対象ドライバの利用
次に、管理対象ドライバを使用するようにTableAdapterを編集します。ソリューション エクスプローラーで、「データセット」を右クリックして「デザイナーの表示」を選択します。データセット デザイナーで「EMPLOYEESTableAdapter」を右クリックし、「プロパティ」を選択します。TableAdapterのプロパティ・ペインで「接続」グループを展開し、「Provider」プロパティを、Oracle.ManagedDataAccess.Clientを使用するように変更します。アプリケーションをリビルドして実行し、今度は管理対象ドライバと連携して動作することを確認します。
以上の変更作業に加えて、使用中のアプリケーションの機能がODP.NET管理対象ドライバでサポートされているかの確認も行います。Oracle Data Provider for .NET Developer’s Guideに、ODP.NETクラスごとに管理対象ドライバの利用がサポートされているかが示されています。この記事の執筆時点で、管理対象ドライバでサポートされていない機能領域、およびサポートが非常に限定的である機能領域として、ユーザー定義型、XMLDBの機能およびデータ型、Oracle Advanced Queuing、クライアントの結果キャッシュ、バルク・コピー、およびOracle Database 12cのTransaction Guard機能などが挙げられます。サポート対象の機能は今後も追加される予定であるため、Oracle Data Provider for .NET Developer’s Guideの“ODP.NET管理対象ドライバと管理対象外ドライバの相違点”を確認するようにしてください。
移行を実施する際には、管理対象ドライバと管理対象外ドライバで接続文字列の解析方法に違いがあることに注意してください。管理対象ドライバでは、2つの接続文字列に何らかの違いがあれば(接続文字列の属性間に余分な空白があるなど)、これらの文字列は異なるものと見なされます。その結果、追加の接続プールが作成されます。管理対象外ドライバでは、新しい接続プールが必要かどうかを判定する際に、接続文字列の属性のみが比較され、違いがないか確認されます。管理対象外から管理対象への移行テスト中に、不要な接続プールが追加で作成されている場合は、この違いが原因であると思われます。
ODP.NET管理対象ドライバのネットワーク(またはその他の設定)の構成は、管理対象外ドライバの構成と少し異なるところがあります。管理対象ドライバはWindowsレジストリや大半の環境変数を参照せず、特定のOracleホームの位置に関連付けられません。そのため、通常は.NET configファイル(machine.config、app.config、またはweb.configなど)内で構成を行います。必要に応じて、一部の.NET configファイルのエントリで、SQL*Net構成ファイル(TNSNAMES.ORAなど)のロードが可能なディレクトリを指すことができます。.NET configファイルのエントリをまとめて省略したい場合は、SQL*NET構成ファイルをアプリケーションの作業ディレクトリ内に追加するか、SQL*Net EZConnectの接続文字列形式を利用できます。
ODP.NETのインストール時に、machine.configにTNS_ADMINエントリが追加されます。このエントリは、アプリケーションからTNSNAMES.ORA、SQLNET.ORA、およびLDAP.ORAを利用可能するためのディレクトリを指しています。インストール時のデフォルトでは、32ビットか、64ビットのいずれかの.NET Framework(両方ではない)で、machine.configが更新されます。32ビットと64ビットの両方の.NET Frameworkを構成する場合、ダウンロードしたパッケージによっては、Oracleホーム内のODP.NET\managedディレクトリにある該当するconfigure.batファイルを手動で実行する必要があります。
このTNS_ADMINエントリを参照するには、マシン上の32ビット.NET Framework向けのmachine.configファイルを開き(32ビットODP.NETをインストールしたため)、TNS_ADMINを検索します。図4のようなエントリを確認できます。
図4:ODP.NETのインストール時にmachine.configが変更され、TNS_ADMINエントリが追加される
machine.configのTNS_ADMIN値が指すTNSNAMES.ORA内でSQL*Net接続エイリアスを使用するのに加えて(または使用する代わりに)、.NET configファイル内に定義を追加することもできます。アプリケーションで使用されるapp.configファイルに接続エイリアスを追加するには、ソリューション エクスプローラーでApp.configをダブルクリックしてエディタで開きます。抽出したdownload.zipファイルに含まれるappconfig.txtファイルの内容を追加します(リスト2に、同様のappconfigalias接続エイリアスを含むサンプルのApp.configファイルの内容を示します)。先ほど編集したアプリケーション・コードを開き、接続文字列の変数値conStringを、Data Source=appconfigaliasとなるように変更します。アプリケーションをリビルドして再度実行します。フォームのボタンをクリックし、作成したApp.configデータソースによって、接続とデータの取得ができることを確認します。
コード・リスト2:ODP.NET管理対象ドライバ用のパラメータを含むサンプルのApp.configの内容
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<oracle.manageddataaccess.client>
<version number="*">
<dataSources>
<dataSource alias="appconfigalias" descriptor="
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)
(HOST=localhost)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=ORCL))) " />
</dataSources>
<settings>
<setting name="TNS_ADMIN" value="C:\tnsfiles"/>
</settings>
<distributedTransaction>
<setting name="OMTSRECO_IP_ADDRESS" value="mydtc" />
<setting name="OMTSRECO_PORT" value="2040" />
<setting name="ORAMTS_SESS_TXNTIMETOLIVE" value="240" />
</distributedTransaction>
</version>
</oracle.manageddataaccess.client>
</configuration>
TNSエイリアス解決の優先順位は次のようになります。ODP.NET管理対象ドライバは、アプリケーションの起動時に、いずれかの.NET configファイルの<oracle.manageddataaccess.client>セクションにあるdataSourcesセクションを検索し、エイリアスが見つかればキャッシュします。次に、いずれかの.NET configファイルでTNS_ADMIN設定を検索し、TNS_ADMINが指すディレクトリ内にあるTNSNAMES.ORAファイルのエントリをキャッシュします。.NET configファイルにdataSourcesセクションもTNS_ADMIN設定もない場合は、アプリケーションの作業ディレクトリ内にあるTNSNAMES.ORAファイルをロードします。
ダウンロード
参照
ODP.NETフォーラム
TwitterでOracleDOTNETをフォロー
その他の多くのパラメータ値を.NET configファイル内で設定できます。ODP.NET管理対象ドライバのその他の設定については、Oracle Data Provider for .NET Developer’s Guideの“Oracle Data Provider for .NET, Managed Driver Configuration”を参照してください。
多くの.NETアプリケーションでは分散トランザクションが利用されます。分散トランザクションとは、Oracle Databaseの表とMySQLのデータベース表といった複数のリソースに影響するトランザクションです。分散トランザクションをコミットするには、関係するすべてのデータベースで、データへのあらゆる変更が永続化することを保証する必要があります。この保証ができないデータベースが1つでもあれば、そのトランザクションでのデータへの変更をすべてロールバックする必要があります。.NETプログラミングでは、分散トランザクションはSystem.Transactions経由で実行できます。System.Transactionsは、WindowsとともにインストールされるサービスであるMicrosoft Distributed Transaction Coordinator(MSDTC)を利用します。
ODP.NET管理対象ドライバで分散トランザクションを実現するには、Oracle.ManagedDataAccess.dllとともに、Oracle.ManagedDataAccessDTC.dllアセンブリもデプロイする必要があります。このDLLは、OracleホームのODP.NET\managed\x86とODP.NET\managed\x64の両方のディレクトリにあります。ディレクトリ名から分かるように、32ビットWindows用のアセンブリと64ビットWindows用のアセンブリがあります。このDLLは必要なときに暗黙的にロードされるため、プロジェクトの参照設定には追加しないでください。
このアセンブリのデプロイの他に、問題のあるトランザクションを解決するためのOraMTSリカバリ・サービスにアクセスできるようにする必要があります。そうしなければ、“ORA-1591: lock held by in-doubt distributed transaction”などのエラー・メッセージが表示されるようになります。OraMTSは、Oracle Data Access ComponentsおよびWindows用Oracle Databaseのインストールに含まれており、このサービスは、アプリケーションと同じマシン上かMSDTCサービスを適切に構成しているリモート・マシン上にインストールできます。リカバリ・サービスをリモート・マシン上で実行する場合は、.NET configファイルの<distributedtransaction>セクションにあるOMTSRECO_IP_ADDRESSとOMTSRECO_PORTの値を設定することで、ODP.NETに対してリカバリ・サービスの場所を指定できます(リスト2を参照)。
この記事では、ODP.NET管理対象ドライバのインストール、移行、および構成について段階的に説明しました。ぜひこのドライバを実際にダウンロードして試し、ご感想をODP.NETフォーラム までお寄せください。
Christian Shayは、オラクルの.NET Technologiesグループ担当Product Managerです。