O/Rマッパー Kairyu ver.0.5.0.0
ORマッパー Kairyu 0.5 がほぼ形になったので公開。
Kairyu とは
コネクションを隠蔽しないシンプルなO/Rマッパーです。 単調かつ大量に発生するObject Relation変換コーディングを減らすために作られました。
ver0.5はver0.3の内容をフルスクラッチ、仕様見直ししてますので、まだCodePlexへは反映させてません。
概要
機能
全般
- クラス名・テーブル名の変換処理を任意に差し替え可能
- プロパティ名・列名の変換処理を任意に差し替え可能
- 主キー列命名規約変更可能
読み込み
- 主キー検索対応
- 全件取得対応
- 無制限上層カスケード対応
- 上層カスケード階層数の指定可
- 外部結合対応
- 1階層下層読み込み対応
- 基底クラスを別テーブルに分離可能
書き込み
- シーケンス対応
- カスタムキー生成対応
- バージョンキー対応(楽観的排他制御)
- 無制限下層カスケード対応
- ダーティチェック対応
- オートナンバー対応
- 追加・更新タイムスタンプ対応
- 追加・更新システム情報対応(追加者、更新者などの情報)
そのほか
SQLServerのみDDLサポート(ユニットテスト上必要だったので)
使い方
全文を載せるとさすがに冗長ですので、イメージにのみ記載。 詳しくは添付ファイルのユニットテストコードを参照してください。
モデル定義
主キーにマッピングされるプロパティの名前はクラス名+”ID”の命名規則に合わせる必要があります。*1 命名規則に合わない場合はKey属性をつけることでキーと判断させることができます。
Public Class Test
Public Property TestID As Integer
Public Property TestName As String
Public Property Lowers As ICollection(Of LowerTest)
End Class
Public Class LowerTest
<Key>
Public Property Test As Test
Public Property LowerTestID As Integer
Public Property LowerTestName As String
End Class
DB接続
これが基本になります。 ModelLoaderクラスにIDbConnectionを参照できるプロパティがありますので、 ORMを使用しないクエリを実行する場合はそちらからIDbCommandを作成してください。
Dim DB As New SqlServerDB("Data Source=.\SQLEXPRESS;Initial Catalog=tempdb;Integrated Security=True")
DB.Connect(
Sub(r As ModelLoader)
'Any Code
End Sub)
DDL(SQLServer)
第1引数にコネクション、第2引数にテーブルを作成したい型を渡す。 第2引数には型は配列可です。
DB.Connect(
Sub(r)
SqlServer.TableCreater.Execute(r.Connection, GetType(Test))
End Sub)
IF EXISTS (SELECT * FROM sysobjects WHERE name='Test' AND xtype='U') DROP TABLE Test;
CREATE TABLE Test (TestID int NOT NULL, TestName nvarchar(200) NOT NULL,CONSTRAINT PK_Test PRIMARY KEY(TestID));
全件検索
Dim lst As List(Of Test) = Nothing
DB.Connect(
Sub(r)
lst = r.Load(Of Test).ToList
End Sub)
SELECT T0.TestID T0_0, T0.TestName T0_1
FROM Test T0
主キー検索
実際にはパラメータクエリが実行されてますが、イメージとしてハードコーディングした場合のSQLを併記します。
Dim c As Test = Nothing
DB.Connect(
Sub(r)
c = r.Load(Of Test)(New Test With {.TestID = 1}).ToItem
End Sub)
SELECT T0.TestID T0_0, T0.TestName T0_1
FROM Test T0
WHERE T0.TestID = '1'
上層カスケード読み込み
FullCascadeで無制限上層カスケードになります。 階層を指定したい場合はCascade(level As Integer)で指定します。 なお、level=0とすると、カスケードなし。level=1とすると、1階層のみ上層へカスケードします。
DB.Connect(
Sub(r)
c = r.Load(Of Test)(New Test With {.TestID = 1}).FullCascade.ToItem
End Sub)
SELECT T0.TestID T0_0, T0.TestName T0_1, T0.Layer2ID T0_2, T0.NullLayer2ID T0_3, T1.Layer2Name T1_1, T1.Layer3ID T1_2, T2.Layer3Name T2_1
FROM Test T0
INNER JOIN Layer2 T1 ON T0.Layer2ID = T1.Layer2ID
INNER JOIN Layer3 T2 ON T1.Layer3ID = T2.Layer3ID
WHERE T0.TestID = '1'
下層カスケード読み込み
下層は一括では取得できないので、2段階に分けて読み込みします。
DB.Connect(
Sub(r)
c = r.Load(Of Test)(New Test With {.TestID = 1}).ToItem
c.Lowers.ToQuery.FullCascade.Fetch()
End Sub)
SELECT T0.TestID T0_0, T0.TestName T0_1
FROM Test T0
WHERE T0.TestID = '1'
/
SELECT T0.TestID T0_0, T0.LowerTestID T0_1, T0.LowerTestName T0_2
FROM LowerTest T0
WHERE T0.TestID = '1'
追加
トランザクション処理になりますので、Transactを使用してDBにアクセスします。 ModelSaverはModelLoaderを継承していますので、上述に挙げた読み込み処理も実行可能です。
DB.Transact(
Sub(r As ModelSaver)
r.SaveAsNew(New Test With {.TestID = 1, .TestName = "Test1"})
End Sub)
INSERT INTO Test (TestID, TestName) VALUES ('1', 'Test1')
削除
DB.Transact(
Sub(r)
r.SaveAsDelete(New Test With {.TestID = 1})
End Sub)
DELETE FROM Test WHERE TestID = '1'
更新
ダーティチェックをするためにStorageクラスに現状を記憶させておく必要があります。 SaveメソッドはStorageに登録されているアーカイブ値をもとに、自動的に追加・更新・削除処理が行われます。 下層カスケードもサポート。
DB.Connect(
Sub(r)
c = r.Load(Of Test)(New Test With {.TestID = 21}).ToItem()
c.Lowers.ToQuery.Fetch()
End Sub)
Dim s As New Storage(c)
c.Lowers.Remove(c.Lowers.First)
c.Lowers.First.LowerTestName = "Update"
c.Lowers.Add(New LowerTest With {.LowerTestID = 3, .LowerTestName = "Add"})
DB.Transact(
Sub(r)
r.Save(s.ToDirtyObjects(c))
End Sub)
INSERT INTO LowerTest (TestID, LowerTestID, LowerTestName) VALUES ('21', '3', 'Add')
/
DELETE FROM LowerTest WHERE TestID = '21' AND LowerTestID = '1'
/
UPDATE LowerTest SET LowerTestName = 'Update' WHERE TestID = '21' AND LowerTestID = '2'