NHibernate HQL生成器缓存表达式

时间:2014-05-30 09:38:12

标签: sql nhibernate hql linq-to-nhibernate

我创建了以下NHibernate HQL生成器:

public class ContainsGenerator : BaseHqlGeneratorForMethod {
    public ContainsGenerator() {
        SupportedMethods = new[] {
            ReflectionHelper.GetMethodDefinition(() =>
                MyExtensions.Contains(null, null))
        };
    }

    public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject,
        ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder,
        IHqlExpressionVisitor visitor) {
        var exp = FormatExpression((string)((ConstantExpression)arguments[1]).Value);

        return treeBuilder.BooleanMethodCall("CONTAINS", new[] {
            visitor.Visit(arguments[0]).AsExpression(),
            treeBuilder.Constant(exp)
        });
    }

    private string FormatExpression(string exp) {
        exp = exp.Replace("'", "''");
        exp = exp.Replace("\"", "");
        exp = (char)34 + Regex.Replace(exp,
           "(AND NOT|AND|OR NOT|OR) ",
           (char)34 + " $1 " + (char)34, RegexOptions.IgnoreCase)
           + (char)34;

        return exp;
    }
}

这用于进行全文搜索,以加快对大型表的搜索。

我过去构建的这个和以前的生成器的唯一区别是我调用FormatExpression将搜索表达式转换为SQL Server理解的正确格式。然而,这似乎是问题,因为虽然它第一次触发查询时工作,但后续搜索产生相同的查询,而传递给CONTAINS的第二个参数永远不会改变。例如,如果我说:

var products = session.Query<Product>().Where(p => p.Name.Contains("Test 1")).ToList();

它将产生以下查询:

  

选择product0_.Id为Id2_,          product0_.Name作为Name2_,来自[dbo] .Products product0_ where CONTAINS(product0_.Name,&#39;&#34; Test 1&#34;&#39;)

现在,如果我说:

var products = session.Query<Product>().Where(p => p.Name.Contains("Test 2")).ToList();

它产生完全相同的查询。

如果有人能告诉我正确的方法,我会很感激。感谢

1 个答案:

答案 0 :(得分:1)

这是NHibernate中的已知错误:请参阅https://nhibernate.jira.com/browse/NH-2658