読者です 読者をやめる 読者になる 読者になる

ADO.NET用の社内ライブラリ、今までどうにも使いにくいライブラリしかなくてだましだまし使ってのですが、ここに来てモデル部分の実装とライブラリの使い方がまったくかみ合わずに実装しにくいことこの上ない、ってことで、本腰入れてラッパークラス作るかと。

''' <summary>
''' ADOでのデータベース接続を管理するラッパークラス
''' </summary>
Public Class AdoConnection
    Dim FConnection As OleDb.OleDbConnection
    Dim FTransaction As OleDb.OleDbTransaction
    Dim FLockCount As Integer

    Public Sub New()
        ConnectionString = ""
        initialize()
    End Sub

    Public Sub New(ByVal aConnectionString As String)
        ConnectionString = aConnectionString
        initialize()
    End Sub

    Private Sub initialize()
        TimeOut = 60
        FConnection = Nothing
        FTransaction = Nothing
        FLockCount = 0
    End Sub

    ''' <summary>
    ''' データベースに接続し、接続オブジェクトを返す
    ''' </summary>
    Public Function Connect() As OleDb.OleDbConnection
        If FConnection Is Nothing Then
            FConnection = New OleDb.OleDbConnection(ConnectionString)
        End If

        If FConnection.State = ConnectionState.Closed Then
            FConnection.Open()
        End If

        Return FConnection
    End Function

    ''' <summary>
    ''' データベースから切断し、接続オブジェクトを解放する
    ''' LockCountが1以上であればなにもしない
    ''' </summary>
    Public Sub Disconnect()
        If LockCount = 0 Then
            If Not FConnection Is Nothing Then
                FConnection.Close()
                FConnection = Nothing
            End If
        End If
    End Sub

    ''' <summary>
    ''' トランザクションを開始し、トランザクションオブジェクトを取得する
    ''' </summary>
    Public Function beginTransaction() As OleDb.OleDbTransaction
        If FConnection Is Nothing Then
            Throw New Exception("データベースに接続していない時にトランザクションを開始しようとしました。")
        End If

        FTransaction = FConnection.BeginTransaction
        Return FTransaction
    End Function

    ''' <summary>
    ''' トランザクションをコミットする
    ''' </summary>
    Public Sub Commit()
        FTransaction.Commit()
        FTransaction = Nothing
    End Sub

    ''' <summary>
    ''' トランザクションをロールバックする
    ''' </summary>
    Public Sub Rollback()
        FTransaction.Rollback()
        FTransaction = Nothing
    End Sub

    ''' <summary>
    ''' ロックカウントを+1する
    ''' </summary>
    Public Function Lock() As Integer
        FLockCount = FLockCount + 1
        Return FLockCount
    End Function

    ''' <summary>
    ''' ロックカウントを-1する
    ''' </summary>
    Public Function UnLock() As Integer
        FLockCount = FLockCount - 1
        Return FLockCount
    End Function

    ''' <summary>
    ''' ロックカウントを強制的に0にする
    ''' </summary>
    Public Sub ForceUnlock()
        FLockCount = 0
    End Sub

    ''' <summary>
    ''' ロックカウントを取得
    ''' </summary>
    Public ReadOnly Property LockCount As Integer
        Get
            If FLockCount <= 0 Then
                Return 0
            Else
                Return FLockCount
            End If
        End Get
    End Property

    ''' <summary>
    ''' ConnectionString
    ''' </summary>
    Public Property ConnectionString As String

    ''' <summary>
    ''' SQLのタイムアウト(秒)
    ''' </summary>
    Public Property TimeOut As Integer

    ''' <summary>
    ''' 接続中のコネクション
    ''' </summary>
    Public ReadOnly Property Connection As OleDb.OleDbConnection
        Get
            Return FConnection
        End Get
    End Property

    ''' <summary>
    ''' トランザクション
    ''' </summary>
    Public ReadOnly Property Transaction As OleDb.OleDbTransaction
        Get
            Return FTransaction
        End Get
    End Property

    ''' <summary>
    ''' トランザクション下にあるか
    ''' </summary>
    Public ReadOnly Property AtTransaction As Boolean
        Get
            Return Not (FTransaction Is Nothing)
        End Get
    End Property
End Class

トランザクションの管理がモデルクラスの実装任せなところはありますが、それでも、コネクション管理オブジェクトを引き回すことでクラスの実装ごとにコネクションを独自管理するよりは、遙かに楽になりますよと。