HierarchyId作为NHibernate sp_executesql调用中的类型化参数

时间:2016-08-26 19:47:38

标签: c# linq nhibernate

我试图找到一种方法使NHibernate(sp_executesql)发送的执行查询到数据库以使用自定义sql数据类型。我在C#中获得了Linq表达式,我尝试运行并使用自定义HqlGenerator来支持IsDescendantOf的{​​{1}}方法。

HierarchyId的我的C#属性当前被表示为字符串(不需要HierarchyId表示的复杂性。)

但问题是发送到Microsoft.SqlServer.Types的结果字符串表明传递的参数是sp_executesql,无论我根据映射改变了什么。但这导致我的NVARCHAR(400)字段的索引出现问题,查询超时,因为它根本没有使用我的索引。但是只要我将参数类型更改为HierarchyId,它就会在0到1秒内运行。因此,我试图找到一种方法来获取HierarchyId语句来指定发送的参数是sp_executesql而不是HierarchyId

我尝试更改映射中的类型,我尝试在映射中更改自定义SqlType。我不确定如何影响NHibernate以手动指定调用NVARCHAR(4000)的类型。

此时我真的需要一个解决方案,但我不确定NHibernate的内部如何确定参数的类型。

已更新为代码

C#代码  我正在处理的场景的简化表达式

sp_executesql

我的ClaimSubmission类上的Hierarchy属性是一个字符串字段。使用var currentUserScopedHierarchy = "/11/"; session.Query<ClaimSubmission>() .Where(x => x.Hierarchy.IsDescendantOf(currentUserScopedHierarchy)) .OrderByDescending(x => x.DateCreated).ToList(); HqlGenerator,SQL Server Profiler中观察到的SQL如下所示

SQL

IsDescendantOf

问题在于最后一位参数的值为&#34; / 11 /&#34;正在作为exec sp_executesql N'/* [expression] */select claimsubmi0_.ObjectId as ObjectId22_, claimsubmi0_.DateCreated as DateCrea2_22_, claimsubmi0_.DateModified as DateModi3_22_, claimsubmi0_.Name as Name22_, claimsubmi0_.SearchText as SearchText22_, claimsubmi0_.CreatedBy as CreatedBy22_, claimsubmi0_.ModifiedBy as ModifiedBy22_, claimsubmi0_.OwnerId as OwnerId22_, claimsubmi0_.Hierarchy as Hierarchy22_, claimsubmi0_.TypeId as TypeId22_, claimsubmi0_.Terminate as Terminate22_ from PseudoObjects claimsubmi0_ where /* removed extra code here that delt with discriminators that isn't relevant */ claimsubmi0_.Hierarchy.IsDescendantOf(@p0) = 1 order by claimsubmi0_.DateCreated desc' ,N'@p0 nvarchar(4000)' ,@p0=N'/11/' 传递。这样,这个查询大约需要20秒(30+一次我添加回其他逻辑,我删除了以获得更简化的示例),这是因为数据类型导致它忽略我的索引。如果我将类型更改为NVARCHAR(400),则查询是即时的。如果我在调用HierarchyId的同时运行查询并内联参数值,那么它也是即时的。

HqlGenerator相关

扩展方法

sp_executesql

如果它是相关的,那么这里也是HqlGenerator

    public static bool IsDescendantOf(this string childHierarchy, string parentHierarchy)
    {
        return childHierarchy.StartsWith(parentHierarchy);
    }

作为NHibernate设置的一部分,我有这个

public class IsDescendantOfGenerator : BaseHqlGeneratorForMethod
{
    public IsDescendantOfGenerator()
    {
        SupportedMethods = new[]
            {
                ReflectionHelper.GetMethodDefinition(() => ExtensionMethods.IsDescendantOf(null, null))
            };
    }

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

0 个答案:

没有答案