Soma 0.13.0.0 リリース

F#で作ったO/Rマッパー Soma 0.13.0.0をリリースしました(F#はもちろんC#VB.NETでも使えます)。ぜひお試しください。

今回のリリースは、Release Candidateの位置づけです。
7月までにはStableな1.0.0.0としてリリースしたいと考えています。

Release Notes
  • New Feature - エンティティを生成するPowerShellスクリプトが利用できるようになりました。
  • Change - F#の ? 演算子を使った自動キャストがサポートされました。
  • Change - Sql.parse関数にCompiledNameAttributeが付与されました。
  • Change - キャッシュ制御をサポートするためにIDbConfigのAPIが変更されました。
  • Change - FindとQueryのパフォーマンスが向上しました。

PowerShellスクリプトでコードの自動生成

DBスキーマを読んでエンティティクラスのコードを自動生成するPowerShellスクリプトを用意しました。
次のような感じで実行できます。

PS C:\Soma\script> .\gen-cs.ps1 -invariant "System.Data.SqlClient" -connectionString "Data Source=.;Initial Catalog=Soma.Tutorial;Integrated Security=True" -namespace "Sample" > Sample.cs

F#、C#VB.NET、それぞれごとのコードを生成できます。

詳しくはドキュメントをどうぞ。

スクリプトを見てみたい方はこのあたりをどうぞ。

F#の ? 演算子で自動キャスト

F#は静的に型付けされた言語ですので、通常は、型を変換する場合は明示的な操作が必要です。ですが、特定の条件化で動的に型変換を行えるようにしました。
例を見てもらえるとなんとなくわかってもらえると思います。

let empList = MyDb.query<dynamic> "select EmployeeId from Employee where EmployeeId = 1" <@ () @>
empList |>
List.iter (fun emp ->
printfn "int : %d, string : %s, bool : %b" emp?EmployeeId emp?EmployeeId emp?EmployeeID
match emp?EmployeeId with
| Some id -> printfn "optional int : %d" id
| _ -> printfn "none.")

出力結果
int : 1, string : 1, bool : true
optional int : 1

ある値が、intになったりstringになったりboolになったり、さらにはoption型として扱えていることがわかります。

他のO/Rマッパーとの比較

今回もパフォーマンスチューニングやりました。テストの方法については前々回のエントリを見てください。
前々回、前回、今回でどう改善したかみてみます。

前々回 : Soma 0.11.0.0と他のO/Rマッパーとの比較
順位 O/R マッパー 時間
1 hand coded took 149ms
2 Mapper Query took 151ms
3 PetaPoco (Fast) took 151ms
4 PetaPoco (Normal) took 154ms
5 Dynamic Massive ORM Query took 158ms
6 Dynamic Mapper Query took 160ms
7 BLToolkit took 187ms
8 Linq 2 SQL Compiled took 192ms
9 Simple.Data took 195ms
10 SubSonic Coding Horror took 218ms
11 Entity framework CompiledQuery took 229ms
12 NHibernate SQL took 242ms
13 Soma : Find took 278ms
14 NHibernate HQL took 285ms
15 Linq 2 SQL ExecuteQuery took 320ms
16 Soma : Query took 347ms
17 Linq 2 SQL took 850ms
18 Entity framework ExecuteStoreQuery took 920ms
19 Entity framework ESQL took 964ms
20 Entity framework took 1225ms
21 Entity framework No Tracking took 1245ms
22 SubSonic ActiveRecord.SingleOrDefault took 4785ms
前回 : Soma 0.12.0.0と他のO/Rマッパーとの比較
順位 O/R マッパー 時間
1 hand coded took 152ms
2 Mapper Query took 154ms
3 PetaPoco (Fast) took 154ms
4 PetaPoco (Normal) took 159ms
5 Dynamic Massive ORM Query took 160ms
6 Dynamic Mapper Query took 161ms
7 Simple.Data took 176ms
8 BLToolkit took 186ms
9 Linq 2 SQL Compiled took 192ms
10 SubSonic Coding Horror took 210ms
11 Soma : Find took 214ms
12 NHibernate SQL took 223ms
13 Entity framework CompiledQuery took 224ms
14 NHibernate HQL took 269ms
15 Soma : Query took 279ms
16 Linq 2 SQL ExecuteQuery took 313ms
17 Linq 2 SQL took 769ms
18 Entity framework ExecuteStoreQuery took 882ms
19 Entity framework ESQL took 890ms
20 Entity framework took 1117ms
21 Entity framework No Tracking took 1124ms
22 SubSonic ActiveRecord.SingleOrDefault took 4654ms
今回 : Soma 0.13.0.0と他のO/Rマッパーとの比較
順位 O/R マッパー 時間
1 hand coded took 145ms
2 Dynamic Massive ORM Query took 149ms
3 PetaPoco (Fast) took 149ms
4 PetaPoco (Normal) took 155ms
5 Mapper Query took 156ms
6 Dynamic Mapper Query took 159ms
7 Simple.Data took 170ms
8 Linq 2 SQL Compiled took 185ms
9 BLToolkit took 191ms
10 Soma : Find took 198ms
11 SubSonic Coding Horror took 199ms
12 NHibernate SQL took 215ms
13 Soma : Query took 218ms
14 Entity framework CompiledQuery took 221ms
15 NHibernate HQL took 263ms
16 Linq 2 SQL ExecuteQuery took 306ms
17 Linq 2 SQL took 772ms
18 Entity framework ExecuteStoreQuery took 876ms
19 Entity framework ESQL took 921ms
20 Entity framework took 1117ms
21 Entity framework No Tracking took 1121ms
22 SubSonic ActiveRecord.SingleOrDefault took 4665ms


比較からわかることは

  • Findの順位が前々回の13位、前回の11位から今回の10位へ
  • Queryの順位が前々回の16位、前回の15位から今回の13位へ

確実に改善できました!