VB.NETで作る!

VB.NETに関するあれこれ

Kairyu 0.5.0.2 beta リリース

Kairyu - object relation mapping framework - Home

主な変更点

  • Type.MakeGenericTypeをキャッシュ化するなど、パフォーマンス改善してます。

  • IDbConnection.ToLoaderIDbTransaction.ToSaver拡張メソッドを用意。IoCとの親和性を上げています。

  • 一部クラス名を変更(Entityに名称統一)。

拡張メソッドのサンプル

Dim c As Sample = Nothing
Using cn As IDbConnection = New SqlClient.SqlConnection(My.Resources.SQL_SERVER_CNSTRING)
    cn.Open()
    c = cn.ToLoader("@").Load(Of Sample).IdSearch(1).ToItem
End Using
Dim c As Sample = Nothing
Using cn As IDbConnection = New SqlClient.SqlConnection(My.Resources.SQL_SERVER_CNSTRING)
    cn.Open()
    Using trn As IDbTransaction = cn.BeginTransaction
        trn.ToSaver("@").SaveAsNew(New Sample With {.SampleID = 2, .SampleName = "Sample2"})
        trn.Commit()
    End Using
    c = cn.ToLoader("@").Load(Of Sample).IdSearch(2).ToItem
End Using

文字「@」はパラメータの接頭語コードです。SQL Serverの場合は「@」、Oracleの場合は「:」を指定してください。

参考:旧来の書き方

DBクラスを用いた記述は、現在も引き続き利用可能です。

メリット

コネクション、トランザクションをラッピングしているため、以下のメリットがあります。

  • トランザクションの記述を短くできます。
  • 例外処理(ロールバックして、例外再発生)の共通化ができます。
  • DBクラスを用いてでもIDbConnectionは取得できるのでベンダーロックインみたいなことは発生しません。

デメリット

多少のデメリットはありますが、致命的なものはありません。

  • 完全にKairyu独自の書き方になるため、学習コストが多少増します。
  • デリゲート内で文法ミスがあると、ブロック全体に赤波線が出るので多少見づらい。*1

サンプルコード

Dim c As Sample = Nothing
Dim db As New SqlServerDB(My.Resources.SQL_SERVER_CNSTRING)
db.Connect(
    Sub(r)
        c = r.Load(Of Sample).IdSearch(1).ToItem
    End Sub)
Dim c As Sample = Nothing
Dim db As New SqlServerDB(My.Resources.SQL_SERVER_CNSTRING)
db.Transact(
    Sub(r)
        r.SaveAsNew(New Sample With {.SampleID = 2, .SampleName = "Sample2"})
        c = r.Load(Of Sample).IdSearch(2).ToItem
    End Sub)

ソースコード

Kairyu.Database.DB、Kairyu.Database.SqlServerDB

''' <summary>
''' データベースコネクションを管理するクラス
''' </summary>
''' <remarks></remarks>
Public Class DB

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    Public Sub New(cnActivator As Func(Of IDbConnection), connection As String, paramPrefix As String)
        Me.ConnectionActivator = cnActivator
        Me.ConnectionString = connection
        Me.ParameterPrefix = paramPrefix
    End Sub

    ''' <summary>
    ''' コネクションアクティベータ
    ''' </summary>
    Private Property ConnectionActivator As Func(Of IDbConnection)

    ''' <summary>
    ''' 接続文字列
    ''' </summary>
    Friend Property ConnectionString As String

    ''' <summary>
    ''' パラメータ接頭語
    ''' </summary>
    Private Property ParameterPrefix As String

    ''' <summary>
    ''' 接続します
    ''' </summary>
    ''' <param name="callback">メインロジックへのコールバック</param>
    ''' <remarks></remarks>
    Public Sub Connect(callback As Action(Of Loader))
        If callback Is Nothing Then Throw New ArgumentNullException("callback")

        Using cn As IDbConnection = Me.ConnectionActivator.Invoke
            cn.ConnectionString = Me.ConnectionString
            cn.Open()
            Dim r As New Loader(cn, Me.ParameterPrefix)
            callback.Invoke(r)
        End Using
    End Sub

    ''' <summary>
    ''' トランザクションします
    ''' </summary>
    ''' <param name="callback">メインロジックへのコールバック</param>
    ''' <remarks></remarks>
    Public Sub Transact(callback As Action(Of Saver))
        If callback Is Nothing Then Throw New ArgumentNullException("callback")

        Using cn = Me.ConnectionActivator.Invoke
            cn.ConnectionString = Me.ConnectionString
            cn.Open()

            Using trn = cn.BeginTransaction
                Try
                    Dim r = Saver.Create(trn, Me.ParameterPrefix)
                    callback.Invoke(r)
                    trn.Commit()
                Catch ex As Exception
                    trn.Rollback()
                    Throw
                End Try
            End Using
        End Using
    End Sub
End Class

''' <summary>
''' SQL Serverのコネクションを管理します
''' </summary>
''' <remarks></remarks>
Public Class SqlServerDB
    Inherits DB

    Public Sub New(connection As String)
        MyBase.New(Function() New SqlClient.SqlConnection, connection, "@")
    End Sub
End Class

*1:コーディング時の瞬間的な問題。Kiaryuがどうというわけではなく、VSの問題。

. .