Linq式の変換について厄介な質問があります。よく調べてみましたが、この件をカバーしていると思われるものは見つかりませんでした。少なくともラムダの作成とメソッドへの受け渡しに関しては、Linqにかなり精通していますが、Expressionに関するものはやや弱いです。
まず、いくつかのコンテキスト:私は多くのDDD風のプロジェクトで使用されているNHibernateに基づく一般的な永続化ソリューションを持っています。アグリゲート内の特定の子のコレクションが本質的に無限である(つまり、実際には非常に大きい)可能性がある特殊なケースでは、コレクション全体をメモリにロードすることは決して受け入れられないため、セットまたはバッグを単純にマップすることはできません。このアーキテクチャでは、APIを使用するコードがリポジトリと直接通信してクエリを実行したり、その方法で結果を制限したりすることはできません。もちろん、APIにコレクションをまったく持たず、代わりに子オブジェクトの関連するサブセットを取得するメソッドを公開することはできません(これが機能しない場合は、これを実行します)が、少し異なることをしようとしています。そして、私はほとんどそれを機能させています...
これらのプロジェクトはFluent(自動マッピングではない)でマッピングされているため、フォームでベースマップクラスにメソッドを追加しました
HasManyQueryable<TCollection>(Expression<Func<T, IQueryable<TCollection>>> memberExpression, Expression<Func<T, TCollection, bool>> selector)
PropertyInfo
このメソッドは、最初のメソッドExpression
(マップするメンバーを指定する)から関連性を導き出します。セレクターExpression
には、通常のNHibernateマッピングの代わりに、親オブジェクトと子オブジェクトの間の関係が含まれています。
User
したがって、ドメインタイプ(T
上記)のセレクターがマップにあるとします。
HasManyQueryable<Transaction>(x => x.Transactions, (u, t) => t.User == u);
これは、指定されたuTransactions
であるすべてのサブセットと、であるプロパティの間のマッピングを指定します。実際のオブジェクトを作成するとき、これを次のように変換する必要がありますTransaction.User
User
User.Transactions
IQueryable<Transaction>
User
Expression<Func<Transaction, bool>> expression = (t => t.User == this)
構築されているオブジェクトthis
はどこにありますか。つまり、にマップする方法を示す一般的なルールを使用して、これをにマップするためのルールに変換しUser
たいと思います。次に、この式を使用して、Linqクエリを実行することにより、リポジトリからを生成できます。Users
Transactions
User
Transactions
IQueryable<Transaction>
return Repository.For<Transaction>().Where(selector);
これは、セレクターがである場合にのみ機能しますFunc<Transaction, bool>
。したがって、私の最終的な必要性は、元の式を変換することです。これにより、が生成さFunc<User, Transaction, bool>
れFunc<Transaction, bool>
ます。
これによりIQueryable
、すべてのクエリ操作がLinqからNHibernateクエリとして実行されるコレクションが得られるため、コレクション全体がメモリに読み込まれることはありません(はい、実際にそれを実行するクエリをフレーム化できることはわかっていますが、コードレビュー時にそれらをキャッチできます)。
ふぅ。それが理にかなっていることを願っています。
私を正しい方向に向けることができるリートエクスプレッションの書き直しスキルを持っている人はいますか?