我正在使用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,使它不會緩存搜索條件的第一個列表?