1

我正在考虑使用 HierarchyId 在 SQL Server 中实现 Hierarchy 数据结构,并且我需要添加可以通过 Linq 使用的扩展方法,以使用在 TSQL 中公开的 HierarchyId 方法。现在我有了通过 HqlGenerator 将 Linq 方法连接到 NHibernate 的所有代码,我只是找不到构建所需 SQL 的正确代码。

因此,例如,对于打击 Linq ......

session.Query<Person>().Where(x=>x.Hierarchy.IsDescendantOf('/1/3/'))

我想最终得到看起来像这样的 SQL...

SELECT people0_.ObjectId, people0_.Name, people0_.Hierarchy
    FROM People people0_
        WHERE people0_.Hierarchy.IsDescendantOf('/1/3/') = 1

我的问题是我无法弄清楚HqlTreeBuilder要在我的类中实现的代码来BaseHqlGeneratorForMethod完成它,因为我需要让该IsDescendantOf方法成为列的子方法,这意味着我需要组合表示层次结构列的表达式以立即出现在之前我的方法调用之间带有点。

我认为这会起作用,但事实并非如此。有什么建议么?

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)
        );
}
4

1 回答 1

0

我最终是这样做的......

我的代码实现

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() });
}

然后你在哪里配置 nHibernate 我有这条线

cfg.AddSqlFunction("_IsDescendantOf", new NHibernate.Dialect.Function.SQLFunctionTemplate(NHibernate.NHibernateUtil.Boolean, "?1.IsDescendantOf(?2) = 1"));

你的类cfg的实例在哪里NHibernate.Cfg.Configuration

于 2014-06-13T14:59:07.783 回答