C#でORM

ここ数ヶ月、今までのTclやRubyとほぼ完全に離れて、C#Windowsアプリケーションを作っている。

そのかなりの時間を費やしたのが、Entity Frameworkというやつだ。
今までWebアプリではRailsActiveRecordを使って、WindowsアプリではXOTcl版のActiveRecordでやってきたので、いわゆるC系やJavaプログラマが標準的に使うデータベースアクセスの方法をほとんど知らなかった。

それで、O/Rマッパーを探したのだが、もうこの世界はゴミの塊のようなライブラリが乱立している。そしてオープンソースのライブラリは何年もメンテナンスされてないものばかり。フリーで完成度の高そうなのはNHibernateくらいだけど、XMLによるマッピングが必要なので却下。

コードジェネレータ付きのやつはあるけど、クラスへのマッピングが不要なのは基本的に存在しない。

Gentle.NET
http://sourceforge.net/projects/gopf

Fluent NHibernate
http://fluentnhibernate.org/

Opf3
http://www.opf3.com/Opf3/

結局、外部のものを使うよりは、Visual Studioが提供するものをつかったほうがよいという結論に至り、DataSetやらLINQ to SQLやらLINQ to Entitiesやらを検討した。どうやらMicrosoftはEntity Frameworkがイチオシということのようだったので、それにしてみたが、もう最悪な日々の連続だった。それでも、C#を礼賛している人々が多いという事実に、そこには何か根拠があるに違いないと思って我慢して、MSDNをはじめとする、たくさんの文献と、スクリーンキャストを参考にしたり、実用性の無いサンプルコードをダウンロードしては、クソ重たいVisual Studio 2008をいちいち立ち上げて、勉強したのだ。

その甲斐あって、ようやくCRUDとアソシエーションを使った作業をほぼまともにできるようになってきた。
そろそろ、ActiveRecordでいうところの、validationやbefore_saveみたいなイベントハンドラに手を付けようとしている。
これも可能ということだが、まあ、ぜんぜん簡単ではないし、無駄にキャストが必要な気がする。

昨日はしばらくVisual Studioを立ち上げていたせいか、カラム追加をEDMに同期させようとしたところ全てが吹っ飛んだのだが、Subversionのおかげで助かった。

ものすごく苦労してできた結果、当たり前のことがようやくできただけだというのに、なんとなく満足してしまう自分がいる。
しかし、仕事は進んでない。

たしかに、こんな複雑なシステムを作って、販売できるMicrosoftの力はすごいと思う。でもいつか まつもとゆきひろさんが、「複雑さを統合開発環境で補完するのは間違いだと思う」、という意味のことを言っていた。いまではその言葉は正しいと身をもって感じる。

早くこんなものを礼賛するのをやめて、C#上でRubyが動くようになることを期待する。Silverlight3ではデスクトップアプリの作成も可能になるらしく、その際Rubyも使えるとのうわさ。それが実現すれば、即刻こんな壮大でクソみたいな仕組みは不要になるはずだから。IronRubyはいつの日か完成を見るのだろうか。。。あまり期待しないほうがよさそうだが。適当なところで妥協して、偽Rubyを作られて中途半端に普及されても困るし。JScriptみたいに。

ちなみに今回難儀したのはEntity Frameworkを使ったせいだけじゃなく、SQLiteを使ったためでもあると思う。ADO.NET 2.0 Provider for SQLiteというフリーのライブラリがあるのだが、これはLINQ to SQLをスキップしてEntity Frameworkに対応してしまったものだが、LINQ to Entityを使った場合にTransactionScopeを使うと自分自身をロックしてしまいSaveChangesがタイムアウトするというバグがある。いや、断言する程よく知らんから、たぶんバグだと思うくらいにしておこう。とにかく、ActiveRecordに比べるともう死にたくなるほどしんどいということだ。

その挙句トランザクションも使えないという。SQLiteトランザクションが使えないということがどれだけ致命的なことか。あ、でもこれはMicrosoftのせいじゃないな。つい言い過ぎた。

たぶん次期バージョンでも魅力的な進化はないだろう。新機能や改善点の分量ではなく、そもそも方向性が違うので。

ADO.NET 2.0 Provider for SQLite (System.Data.SQLite) (パブリックドメイン)
http://sqlite.phxsoftware.com/

dotConnect for SQLite (こっちは商用)
http://www.devart.com/dotconnect/sqlite/

Entity Framework (Entity DesignerはVisual C# Express Editionでも付いてくる)
http://www.atmarkit.co.jp/fdotnet/special/vs2008sp1ef/vs2008sp1ef_01.html

LightSpeed (EFより更新頻度が高いことが売りらしい)
http://www.mindscape.co.nz/Products/LightSpeed/