nHibernate HqlTreeBuilder to implement Linq methods for HierarchyId
我正在考虑使用 HierarchyId 在 SQL Server 中实现 Hierarchy 数据结构,并且我需要添加可以通过 Linq 使用的扩展方法,以使用在 TSQL 中公开的 HierarchyId 方法。现在,我拥有了通过 HqlGenerator 将 Linq 方法连接到 NHibernate 的所有代码,我只是找不到构建所需 SQL 的正确代码。
例如,对于打击 Linq...
1 | session.Query<Person>().Where(x=>x.Hierarchy.IsDescendantOf('/1/3/')) |
我希望得到类似这样的 SQL...
1 2 3 | SELECT people0_.ObjectId, people0_.Name, people0_.Hierarchy FROM People people0_ WHERE people0_.Hierarchy.IsDescendantOf('/1/3/') = 1 |
我的问题是我无法弄清楚要在我的
我认为这会起作用,但事实并非如此。有什么建议吗?
1 2 3 4 5 6 7 | 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) ); } |
我最终是这样做的......
我的代码实现
1 2 3 4 5 6 7 8 | 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); } |
HqlGenerator
1 2 3 4 | 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() }); } |
然后你在哪里配置 nHibernate 我有这行
1 | cfg.AddSqlFunction("_IsDescendantOf", new NHibernate.Dialect.Function.SQLFunctionTemplate(NHibernate.NHibernateUtil.Boolean,"?1.IsDescendantOf(?2) = 1")); |
其中
的实例