我创建了以下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();
它产生完全相同的查询。
如果有人能告诉我正确的方法,我会很感激。感谢