我正在通过扩展 BaseHqlGeneratorForMethod 为 nHibernate 开发自定义 linq 扩展。该技术记录在这里: http: //fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-extension.html
我已经成功地为各种类型的操作实现了这些,但我必须说 - 将一个简单的 linq 表达式转换为其完整的表达式树并不容易!我现在被困在一个上。
对于这个例子,我有三个实体。 Employee
, Group
, 和EmployeeGroup
. EmployeeGroup 类在 Employee 和 Group 之间建立了多对多的关系。我必须专门创建中间类,因为还有其他属性可以跟踪,例如每个员工在每个组中拥有的特定权限。所以有两个一对多的关系,而不是一个 nHibernate 的多对多关系。
现在假设我想获取包含特定员工的所有组。我可以写这个查询:
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
类的源代码。但这并没有考虑到源是原始元素的属性,也没有考虑到我没有 lambda 表达式来表示 where 子句。我需要手动构建这些部分。
到目前为止,发布我的尝试毫无意义,因为它们都离任何可行的方法相去甚远。
有人可以帮我将这个简单的表达式转换为BuildHql
方法覆盖的适当方法集吗?
如果有任何更好的文档,请告诉我。谢谢。