3

NHibernate 3+ と Entity Framework 4.1 をテストするプロジェクトを作成し、リポジトリにラップして、インターフェイスなどを使用して非常にテストしやすくしました。

どちらの ORM もリポジトリの外部に公開したくありません (IQueryables も公開しません)。すべてはそのレイヤーで処理する必要があり、フェッチを抽象的な方法で処理しようとするまでは、すべてがうまくいきました。

積極的な読み込みを追加する Microsoft の実装では、Include 関数でマジック ストリング (yuck) または Linq 式 (yay) を使用します。それらの構文は次のようになります。

IQueryableThing.Include(o => o.Person);
IQueryableThing.Include(o => o.Company.Contact);
IQueryableThing.Include(o => o.Orders.Select(p => p.LineItem.Cost);

1 つ目は、関連する人物をロードするだけです。(親) 2 番目は、関連する会社と各会社の連絡先を読み込みます。(親と祖父母)。3 つ目は、関連するすべての注文、項目、および各注文の費用を読み込みます。

これはかなり洗練された実装です。

Hibernate は少し異なるアプローチを使用します。彼らはまだLinq式を使用していますが、拡張メソッドをより頻繁に使用しています(流暢なアプローチ)。

IQueryableThing.Fetch(o => o.Person);
IQueryableThing.Fetch(o => o.Company).ThenFetch(o => o.Contact);
IQueryableThing.FetchMany(o => o.Orders).ThenFetch(p => p.LineItem).ThenFetch(q => q.Cost);

(3 行目の構文が正しいかどうかはわかりません)

式のリストを別のクラスにカプセル化し、それらの式をそのクラス内の IQueryable に適用できます。したがって、Microsoft 式の構文を標準化し、式ツリーをたどって各式を再構築することで、それを NHibernate の構文に変換する必要があります。

これは本当にトリッキーな部分です。IQueryable の正しい関数を呼び出すために、特定の操作順序を維持する必要があります (Fetch または FetchMany のいずれかで開始し、その後はそれぞれ「ThenFetch」または「ThenFetchMany」にする必要があります)。 ExpressionVisitor クラスで。

編集:最終的に、プロパティ、コレクション、およびコレクションの選択の任意のレベルのネストを取り、式の配列を生成する式パーサーを作成しました。残念ながら、組み込みの Fetch 拡張メソッドは LambdaExpression をパラメーターとして取りません。

私が現在立ち往生している部分は、nHibernate からの組み込みの Fetch 定義を使用できないことです。Remotion ライブラリの関数を直接叩くか、パーサーを満たす独自の拡張メソッドを登録する必要があるようです。

ファンキー。

4

1 に答える 1

0

使ってみましたNHiberanteUtil.Initialize()か?私はあなたがしていることをやろうとはしていませんが、 Initialize はInclude().

于 2011-05-27T14:01:07.677 に答える