我正在使用LINQ到nhibernate来搜索实体名称及其别名。NHibernate LINQ匹配搜索值的集合
class Entity
{
string Name { get; set; }
string[] Aliases { get; set; }
}
enityQueryable.Where(x =>
x.Name.StartsWith(searchParam) ||
x.Aliases.Any(a => a.StartsWith(searchParam)));
这部分工作正常。
我现在有一个要求与可能的搜索词列表匹配。我可以在linq中执行查询,但是正常工作,但是Nhibernate无法将其转换为Hql。
enityQueryable.Where(x => MatchOnNameOrAlias(x));
private bool MatchOnNameOrAlias(Entity e, string[] searchTerms)
{
foreach (var searchTerm in searchTerms)
{
if (e.Name.StartsWith(searchTerm))
{
return true;
}
if (e.Aliases.Any(a => a.StartsWith(companySearchTerm)))
{
return true;
}
}
return false;
}
我开始看使用LinqToHqlGenerator
,实施了relativly直线前进,并在第一次检查出现工作但它仅适用第一次。随后的调用重用相同的搜索参数集合。
public class MatchesAnySearchTermGenerator : BaseHqlGeneratorForMethod
{
public MatchesAnySearchTermGenerator()
{
SupportedMethods = new[] { ReflectionHelper.GetMethod(() => SearchLinqExtensions.MatchesAnySearchTerm(null, null)) };
}
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
var likes = ((IEnumerable<string>)((ConstantExpression) arguments[1]).Value).ToArray();
HqlBooleanExpression lastBooleanExpression = CreateHqlLike(treeBuilder, visitor.Visit(arguments[0]).AsExpression(), likes[0]);
for (int i = 1; i < likes.Length; i++)
{
lastBooleanExpression = treeBuilder.BooleanOr(lastBooleanExpression,
CreateHqlLike(treeBuilder, visitor.Visit(arguments[0]).AsExpression(), likes[i]));
}
return lastBooleanExpression;
}
private HqlLike CreateHqlLike(HqlTreeBuilder treeBuilder, HqlExpression nameExpression, string like)
{
return treeBuilder.Like(nameExpression, treeBuilder.Constant(like + '%'));
}
}
这似乎是一个已知问题。
所以不必恢复到直接使用NHibernate来执行查询和维护我的代码基础上的IQueryable的依赖。有没有替代我的第一个查询,Nhibernate将支持或我可以构造HqlGenerator,使它不会缓存搜索条件的第一个列表?