问题
I have created the following NHibernate HQL generator:
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;
}
}
This is used to do Full-Text searching to speed up searching over large tables.
The only difference to this and previous generators I've built in the past is that I call FormatExpression to convert the search expression to the correct format that SQL Server understands. However this seems to be the problem because although it works the first time I fire the query, subsequent searches produces the same query and the second argument passed into CONTAINS never changes. For example If I say:
var products = session.Query<Product>().Where(p => p.Name.Contains("Test 1")).ToList();
It will produce the following query:
select product0_.Id as Id2_, product0_.Name as Name2_, from [dbo].Products product0_ where CONTAINS(product0_.Name, '"Test 1"')
Now if I say:
var products = session.Query<Product>().Where(p => p.Name.Contains("Test 2")).ToList();
It produces exactly the same query.
I'd appreciate it if someone could show me the correct way to do this. Thanks
回答1:
It is a known bug in NHibernate: see https://nhibernate.jira.com/browse/NH-2658.
来源:https://stackoverflow.com/questions/23951400/nhibernate-hql-generator-caching-expression