1

我正在扩展 NHibernate Linq 提供程序,并且我希望调用具有位参数 [s] 和返回类型的用户定义。

这是 SQL 用户定义的函数签名:

 FUNCTION f_DocumentsFreeTextSearch
 (
     @docId int,
     @searchString varchar(8000),
     @searchTitle bit
 )
 RETURNS bit

这是用于 Linq 使用的“假”扩展方法:

public static class DialectExtensions
{
    public static bool FreeText(this Document doc, string searchString, bool searchTitle)
    {
        return false;
    }
}

这是我的 LinqToHqlGeneratorsRegistry

public sealed class ExtendedLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
    public ExtendedLinqToHqlGeneratorsRegistry()
    {
            DialectExtensions.FreeText(null, null, true)),
            new FreeTextGenerator());
    }
}

这是我的生成器:

public class FreeTextGenerator : BaseHqlGeneratorForMethod
{
    public FreeTextGenerator()
    {
        SupportedMethods = new[]
                               {
                                   ReflectionHelper.GetMethodDefinition(() => DialectExtensions.FreeText(null, null, true))
                               };
    }

    #region Overrides of BaseHqlGeneratorForMethod

    public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
    {
        return treeBuilder.MethodCall("dbo.f_documentsfreetextsearch", arguments.Select(a => visitor.Visit(a).AsExpression()).ToArray());
    }

    #endregion
}

这是所需的用法:

    [TestMethod]
    public void CanFreeText()
    {
        var query = SessionHolder.Current.Query<Document>();
        var list = query.Where(d => d.FreeText("giorno", true)).ToList();            
    }

第一个问题:上面的代码导致了 InvalidCastException:

测试方法 App.Tests.NHMapping.CanFreeText 抛出异常:System.InvalidCastException:无法将“NHibernate.Hql.Ast.HqlMethodCall”类型的对象转换为“NHibernate.Hql.Ast.HqlBooleanExpression”类型。

以这种方式解决(不优雅但有效):

    [TestMethod]
    public void CanFreeText()
    {
        var query = SessionHolder.Current.Query<Document>();
        var list = query.Where(d => d.FreeText("giorno", true) == true).ToList();            
    }

现在NHibernate执行查询,但是生成的SQL是错误的:

测试方法 App.Tests.NHMapping.CanFreeText 抛出异常:NHibernate.Exceptions.GenericADOException: could not execute query [ select [...] from dbo.DOCUMENTS document0_ where case when dbo.f_documentsfreetextsearch(document0_.IDDOCUMENT, @p0, @p1 =1) then 1 else 0 end=@p2 ] Name:p1 - Value:giorno Name:p2 - Value:True Name:p3 - Value:True [SQL: select [...] from dbo.DOCUMENTS document0_ where case when dbo.f_documentsfreetextsearch(document0_.IDDOCUMENT, @p0, @p1=1) then 1 else 0 end=@p2] ---> System.Data.SqlClient.SqlException: '=' 附近的语法不正确。

请注意,生成的 SQL 中的函数调用将 @p1=1 作为第三个参数,并且 WHERE 子句是内联 CASE 而不是

dbo.f_documentsfreetextsearch(document0_.IDDOCUMENT, @p0, @p1) = 1

正如我所料。

如果我在我的 C# 代码中将 bool 参数和返回类型更改为 Int32,则一切正常(但仍然不是很优雅)。

知道如何使所需的语法起作用吗?

提前致谢

克劳迪奥

PS:抱歉有很多代码和错误的文字:P

4

1 回答 1

1

似乎您遇到了与我在使用用户类型作为布尔属性时相同的错误 NH-2839 。在解决此问题之前,您现在无能为力。

于 2012-09-05T18:33:22.800 回答