データベースに依存しない.NETプログラム

以前、私が働いていた会社には、データベースとしてMSAccessを使ったADO.NET 1.0アプリケーションがありました。それをSQLServerに移行する必要があったので、ソースを修正することになりました。それで私たちが行った対応として、データ・プロバイダによってSystem.Data.SqlClient名前空間(SQL Server用)、System.Data.OleDb名前空間(MSAccess用)を、それぞれ使い分けて、別々のコードを書きました。動いてはしましたが、あまりエレガントなソリューションではなかったです。


If strDBMS = "MS SQL Server" Then
Dim sqlCmd As SqlClient.SqlCommand
sqlCmd = sqlCn.CreateCommand()
sqlCmd.CommandText = pSQL
Dim dr As SqlClient.SqlDataReader = sqlCmd.ExecuteReader()
Else
Dim oleDbCmd As OleDb.OleDbCommand
oleDbCmd = oleCn.CreateCommand()
oleDbCmd.CommandText = pSQL
Dim dr As OleDb.OleDbDataReader = oleDbCmd.ExecuteReader()
End If

今働いている会社でも、アプリケーションを1つのDBシステムから他のDBシステムへ移行する必要になりました。今回はSQL ServerからOracleへ。幸いにも、今はプロバイダ・ファクトリ利用することによってADO.NET2.0でデータプロバイダ依存しないコードの書き方が簡単になりました。

プロバイダ・ファクトリ・モデルの概要

プロバイダ・ファクトリは、接続、コマンド、データリーダーなど様々なDB関連オブジェクトのための汎用名前空間として考えられます。System.Data.SqlClientSystem.Data.OleDbなどのようなプロバイダ専用の名前空間に含むデータ型でオブジェクト定義する代わりに、System.Data.Common名前空間に含むベース・クラスを使用します。

しかし、System.Data.Commonに含むクラスはアブストラクト(抽象的)で新しいオブジェクトの作成ができません。コンクリート(具象)のオブジェクトを提供するファクトリを作る必要があります。System.Data.Commonに含むDbProviderFactoriesクラスは、これらのオブジェクトを作成する静的メッソードを提供しています。

サンプル・コード

プロバイダ・ファクトリ・モデルを使った、単純なSelect文を実行するためのサンプル・コードをここに添付します。実際のアプリケーションでは、プロバイダ名と接続文字列をINIファイルや設定ファイルから取得して指定することになります。

サンプルのコードを実行するには、Visual StudioでWindowsフォームアプリケーションを作って、フォームにボタンを追加し、以下のコードを関連づけます。文字列も適当な値にする必要があります。

コードに対するコメントを書き入れましたが、何か質問などがありましたら、このポストに対するコメントを書いて下さい。


Imports System.Data
Imports System.Data.Common
Imports System.Collections.Generic

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

'Oracle用プロバイダ名
Dim myDataProviderName As String = "System.Data.OracleClient"
'接続文字列
Dim myConnectionString As String = "Data Source=testdb;User Id=testuser;Password=testpassword;"

Try
'DBファクトリの作成
Dim gDBFactory As DbProviderFactory = DbProviderFactories.GetFactory(myDataProviderName)

'ファクトリから接続オブジェクトを取得
Dim sqlCn As DbConnection = gDBFactory.CreateConnection

'DB接続を開く
sqlCn.ConnectionString = myConnectionString
sqlCn.Open()

'テーブルの一行を取得
Dim sqlCmd As DbCommand = sqlCn.CreateCommand()
sqlCmd.CommandText = "SELECT field1 FROM table1 where field2 = 'abc'"
Dim dr As DbDataReader = sqlCmd.ExecuteReader()
dr.Read()

'フィールドの値を表示
MessageBox.Show(dr.Item("field1"))

'DB接続を閉じる
sqlCn.Close()
sqlCn.Dispose()

Catch ex As Exception ' エラーをキャッチ
MessageBox.Show(ex.Message.ToString())
Finally
'実際のアプリケーションでは、ここクリンアップコードを書く
End Try
End Sub
End Class

日本語

Topics:

新しいコメントの追加