BaseHqlGeneratorForMethod を拡張することにより、nHibernate のカスタム linq 拡張に取り組んでいます。テクニックはここに文書化されています: http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-extension.html
さまざまな種類の操作でこれらを実装することに成功しましたが、単純な linq 式を完全な式ツリーに変換するのは簡単ではありません。私は今、1つにこだわっています。
この例では、3 つのエンティティがあります。 Employee
、Group
、およびEmployeeGroup
。EmployeeGroup クラスは、Employee と Group の間に多対多の関係を設定します。各従業員が各グループで持つ特定のアクセス許可など、追跡する追加のプロパティがあるため、特に中間クラスを作成する必要があります。したがって、nHibernate の多対多の関係ではなく、2 つの 1 対多の関係があります。
ここで、特定の従業員を含むすべてのグループを取得したいとします。このクエリを書くことができます:
var groups = session.Query<Group>()
.Where(g => g.EmployeeGroups.Any(eg => eg.Employee == employee));
これは問題なく機能しますが、入力するのは大変です。私はむしろこれを行うことができます:
var groups = session.Query<Group>().Where(g => g.HasEmployee(employee));
次のような拡張メソッドを作成することから始めます。
public static bool HasEmployee(this Group group, Employee employee)
{
return group.EmployeeGroups.Any(eg => eg.Employee == employee);
}
これは、グループのローカル リストをクエリするときに機能しますが、nHibernate セッションに対しては機能しません。そのためには、linq 拡張機能も作成して登録する必要があります。記事 (上記のリンク) と同じように、GroupHasEmployeeGenerator
を拡張するクラスを作成しますBaseHqlGeneratorForMethod
。.SupportedMethods
HasEmployee 拡張メソッドを参照するようにそのプロパティを設定しました。
私が迷子になるのは、へのオーバーライドBuildHql
です。構築する式はすぐに複雑になります。私は.Any
句を置き換えているので、組み込みクラスのソースから始めるのが良いでしょうAnyHqlGenerator
。ただし、ソースが元の要素のプロパティであることは考慮されていません。また、where 句を表すラムダ式がないことも考慮されていません。これらのパーツを手動で作成する必要があります。
これまでのところ、私の試みを投稿しても意味がありません.
この単純な式をメソッドのオーバーライドに適した一連のメソッドに変換するのを誰か手伝ってくれませんBuildHql
か?
これに関するより良いドキュメントがあれば、私に知らせてください。ありがとう。