nHibernate HqlTreeBuilder将为HierarchyId实现Linq方法
我正在考虑使用HierarchyId在SQL Server中实现层次结构数据结构,我需要添加可通过Linq使用的扩展方法,以使用TSQL中公开的HierarchyId方法。现在我有了通过HqlGenerator将Linq方法连接到NHibernate的所有代码,但我找不到构建所需SQL的正确代码 例如,对于打击林克nHibernate HqlTreeBuilder将为HierarchyId实现Linq方法,linq,nhibernate,hql,expression-trees,linq-to-nhibernate,Linq,Nhibernate,Hql,Expression Trees,Linq To Nhibernate,我正在考虑使用HierarchyId在SQL Server中实现层次结构数据结构,我需要添加可通过Linq使用的扩展方法,以使用TSQL中公开的HierarchyId方法。现在我有了通过HqlGenerator将Linq方法连接到NHibernate的所有代码,但我找不到构建所需SQL的正确代码 例如,对于打击林克 session.Query<Person>().Where(x=>x.Hierarchy.IsDescendantOf('/1/3/')) 我的问题是我无法找出要
session.Query<Person>().Where(x=>x.Hierarchy.IsDescendantOf('/1/3/'))
我的问题是我无法找出要在BaseHQlGeneratorFormMethod类中实现的HqlTreeBuilder代码,因为我需要将IsDescendaTof方法作为列的子方法,这意味着我需要将表示层次结构列的表达式与中间的点组合在一起,以显示在方法调用之前
我原以为这样行得通,但事实并非如此。有什么建议吗
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
return treeBuilder.Equality(
treeBuilder.Dot(visitor.Visit(arguments[0]).AsExpression(), treeBuilder.MethodCall("IsDescendantOf", new[] {visitor.Visit(arguments[1]).AsExpression()})),
treeBuilder.Constant(1)
);
}
我最终是这样做的 我的代码实现
public static bool IsDescendantOf(this string childHierarchy, string parentHierarchy)
{
//In most cases this will be translated to the SQL implementation by LINQ, but on the off chance it's used on an in memory collection, the simplest implementation
//Is to verify that the child hierarchy starts with the hierarchy of the parent.
//for example....
// "/11/534/2134/".StartsWith("/11/534/") //would be TRUE
return childHierarchy.StartsWith(parentHierarchy);
}
hql发生器
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
return treeBuilder.BooleanMethodCall("_IsDescendantOf", new[] { visitor.Visit(arguments[0]).AsExpression(), visitor.Visit(arguments[1]).AsExpression() });
}
其中cfg是您的NHibernate.cfg.Configuration类的实例支持许多层次结构函数的项目示例如下:。注意,它使用字符串而不是CLR的SqlhierarchyId
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
return treeBuilder.BooleanMethodCall("_IsDescendantOf", new[] { visitor.Visit(arguments[0]).AsExpression(), visitor.Visit(arguments[1]).AsExpression() });
}
cfg.AddSqlFunction("_IsDescendantOf", new NHibernate.Dialect.Function.SQLFunctionTemplate(NHibernate.NHibernateUtil.Boolean, "?1.IsDescendantOf(?2) = 1"));