近頃、Oren Eini氏 (別名Ayende Raheim氏)の記事をきっかけにして、NHibernate と Entity Framework 4.0というふたつの .NET のオブジェクト/リレーショナルマッピングフレームワークについて、それぞれのメリットと能力に関する議論がわき起こった。InfoQはこの議論が与えてくれる視点を理解するため、この議論の詳細に分け入った。
Rahien氏はNHibernateプロジェクトのメンバでもある。氏はNHibernate と Entity Framework 4(EF)の簡単な比較を行った。氏は EF 1.0 から EF 4 への進歩を認めつつも、下記のようないくつかの特徴を並べてNHibernateの方が優れたORMソリューションを提供すると考えている。
- 一括書き込み – NHibernateはすべての書き込みを一括して処理するように構成できます。従って、データベースに対して複数の書き込み処理を実行する必要があるときも個別に実行する代わりに、一回の処理で実行できます。
- 一括読み込み / 複数問い合わせ – NHibernateを使うとデータベースへの複数の問い合わせを、問い合わせごとにするのではなく、1回の処理にまとめられます。
- 一括コレクション読み込み– NHibernateではコレクションを遅延読み込みをするとき、まだ読み込まれていない同じ型の他のコレクションを見つけ、1回の処理で読み込むことができます。これは、N+1の関連のSELECTを回避するための素晴らしい方法です。
- lazy="extra"のコレクション – Lazy extraを使えばNHibernateはコレクション上の処理にうまく適合できます。例えば、blog.Posts.Countの値を取得するときにはコレクション全体を読み込む必要はありません。"select count(*) from Posts where BlogId = 1"という文を生成します。また、blog.Posts.Contains()も同様に1回の問い合わせで済みます。コレクション全体をメモリに読み込むような高価なことはしません。
- コレクションフィルタとページコレクション - エンティティのコレクションに対して追加のフィルタ(ページングもあります!) を定義できます。つまり、blog.Postsコレクションを簡単にページングできますし、全体をメモリに読み込む必要もありません。
- 2次キャッシュ – キャッシュを管理するのは複雑です。以前、2次キャッシュがなぜ重要なのかについて触れましたので、ここには書きません。
- Tweaking – フレームワークが提供する能力を少しでも超えて何かをする必要がある時にはこの機能が致命的に重要になります。NHibernateを使えばほとんどの場合、拡張可能なポイントがあります。EFでは完璧にブロックされています。
- 統合 & 拡張性 – NHibernateにはたくさんの拡張プロジェクトがあります。NHibernate Search、NHibernate Validator、NHibernate Shardsなどです。このようなプロジェクトはEFにはありませんし、そもそも拡張を作ることすらできません。拡張の対象になり得るポイントがないのです。
EF 4を使う利点について、氏は下記のように述べる。
- EF 4.0は現在のNHibernateの実装よりも優れたLinqプロバイダを持っています。この部分は活発に取り組まれている部分であり、NH 3.0はこの差を埋めるでしょう。
- EFはマイクロソフトから提供されています。
NHibernateプロジェクトの著名な貢献者である氏の記事は、様々な賛成/反対の反応を引き起こした。記事の読者であるtobi氏はNHibernateの貧弱なエラーメッセージに不満を漏らしている。
NHibernateを使ってほんの数時間作業をしてみた経験からいうと、手作業でドメインクラスを実装してマッピング(私の場合はFluentNHibernateを使ったのですが)を定義するのは、とても大変な作業になってしまい、エラーメッセージもよくありません。なので私はEF4のほうがいいと思います。
Roy氏はエラーメッセージとドキュメントについて複雑な気持ちを持っている。
EFに賛成の理由としては、NHibernateよりもドキュメントがしっかりしていてエラーメッセージもよりはっきりとしていることです。
とはいっても私はNHibernateの方がまだ好きですが、何か問題が起こったときに様々なブログを調べなければなりません。逆に言えば質問に答えてくれる人がたくさんいるという利点があるということかもしれませんが。
Jimmy Bogard氏はNHibernateのバグ修正の過程がよりNHibernateを魅力的にしていることを理解している。
NHがOSSであるということも優れた点のひとつです。ここ数年私は何度かNHにパッチを当てる必要がありました。バグを修正したり必要な機能を追加したりするためです。EFでは行き詰まってしまいます。
Alex Yakunin氏はテストスイートでありORMツールであるORMBattle.NETの作成に携わっている。氏の不満は、
NHibernateの利点しか示されていないことをはっきりと言うべきだと思います。欠点は全く触れられていません。LINQプロバイダについての話だけでは真実とは少し離れています。例えば、よく知られているケースとしてはEFは変更追跡をサポートしていますが、NHはサポートしていません。この違いはある局面においては性能に大きな影響を与えます(実際には、NHを使った場合は"意図的"に変更追跡をあきらめるべきです。)。
Radenko Zec氏は単体テストとデザイナの能力を比べている。
私が思うに、NHibernateの最大の長所は単体テストに対するサポートが優れていることです。EF4はテスト対象として設計されていません。EF4をつかったソリューションを作って単体テストを書くのはとても難しいです。
しかしEF4がとても使いやすいデザイナ(実際の大規模なプロジェクトではデザイナはとても重要です)を持っていることも事実です。POCO T4 templateはこのデザイナに基づいています。... そろそろデザイナやコードジェネレータを拒否するのをやめてNHibernate用のデザイナを自前て作ることを考えはじめてもいいかもしれません。コミュニティがNHibernate用のデザイナをほしがったら、よいデザイナをあげましょう。... サードパティのデザイナはEF4のデザイナとは比べ物になりません。ひょっとしたらLLBGEN 3はEF4のデザイナと同じ程度の能力があるかもしれませんが、まだリリースされていませんし、商用です。
Frans Bouma氏はORMツールであるLLBLGenProの開発者だ。氏はNHibernateのドキュメントについてとても不十分たと述べている。
EFがNHより優れているのはドキュメントです。また、しっかりした事例や様々な開発者カンファレンスでの多数のエバンジェリストのスピーチもEFを支えていますし、解説記事もひっきりなしにアップされています。 … このような側面(お願いだから言い訳はしないでください。ドキュメントに関しては本当にひどいです。どんなにひどいか知りたい方はNHibernateのDDLSQL文の生成のドキュメントを見てください。どんなにすごい生成ができるのかわかると思います。 ... java classって?)からNHを考えると不十分だと言わざるを得ません。その他の選択肢もあるのですから、NHibernateが本当に優れた点を持っているというわけではないと思います。
Felix氏は両方を合わせた解決策を提案している。
... "OR/Mはコーティングの世界のベトナムだ"...といった人がいたことを忘れてはなりません。NHは退役軍人でEFは新入りです。残念ながらMSはオープンソースに影響力を行使できませんが、できたとしたら話は簡単になります。つまり、MSがデザイナと統合ツールを提供しOR/MはNHを使うのです。これは生産的なソリューションになると思います。
一般的な認識は次のようだ。すなわちNHibernateはEntity Framework 4.0にないような機能を備えている。例えば一括読み取り/書き込み、遅延処理の"extra"属性、コレクションのフィルタなどだ。一方でEntity Frameworkは優れたLINQプロバイダを持っている。またドキュメントもしっかりしていてマイクロソフトによってサポートされている。この議論についてのあなたの考えはどうだろうか。