我正在实现 LINQ 和 Nhibernate 的“IsLike”扩展,如Fabio 的这篇文章中所述。
我有这样的代码:
public class MyLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
public MyLinqToHqlGeneratorsRegistry()
: base()
{
RegisterGenerator(ReflectionHelper.GetMethodDefinition(() =>
MyLinqExtensions.IsLike(null, null)),
new IsLikeGenerator());
}
}
public class IsLikeGenerator : BaseHqlGeneratorForMethod
{
public IsLikeGenerator()
{
SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition(() =>
MyLinqExtensions.IsLike(null, null)) };
}
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject,
ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
return treeBuilder.Like(visitor.Visit(arguments[0]).AsExpression(),
visitor.Visit(arguments[1]).AsExpression());
}
}
public static class MyLinqExtensions
{
public static bool IsLike(this string source, string pattern)
{
pattern = Regex.Escape(pattern);
pattern = pattern.Replace("%", ".*?").Replace("_", ".");
pattern = pattern.Replace(@"\[", "[").Replace(@"\]", "]").Replace(@"\^", "^");
return Regex.IsMatch(source, pattern);
}
}
扩展在配置中注册(第 3 行):
protected void InitializeNHibernateSession()
{
NHibernateConfiguration = NHibernateSession.Init(
new SimpleSessionStorage(),
GetMappingAssemblies(),
GetNHibernateConfig());
NHibernateConfiguration.Properties.Add(
Environment.LinqToHqlGeneratorsRegistry,
typeof(MyLinqToHqlGeneratorsRegistry).AssemblyQualifiedName);
NHibernateSession.RegisterInterceptor(new AuditInterceptor());
}
但是当我尝试运行查询时出现异常
System.NotSupportedException was unhandled by user code
Message=Boolean IsLike(System.String, System.String)
Source=NHibernate
StackTrace:
at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression (MethodCallExpression expression)
at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitExpression (Expression expression)
at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.Visit(Expression expression, VisitorParameters parameters)
at NHibernate.Linq.Visitors.QueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
at Remotion.Data.Linq.Clauses.WhereClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
at Remotion.Data.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1 bodyClauses, QueryModel queryModel)
at Remotion.Data.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
at NHibernate.Linq.Visitors.QueryModelVisitor.Visit()
at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory)
at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
at NHibernate.Linq.NhQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
at MyProject.Data.Specification.LinqSpecRepository`1.FindAllPaged(Specification`1 specification, Int32 currentPage, Int32 noOfItemsPerPage) in c:\source\MyProject\Specification\LinqSpecRepository.cs:line 47
at MyProject.Tests.PersonRepositoryTests_UserSearch.FilteredQuery_CanPerformWildCardAtTheEndSearch() in c:\source\MyProject.Tests\PersonRepositoryTests_UserSearch.cs:line 51
就像扩展未注册或未触发一样。该属性已设置,因为我尝试将其添加到测试本身的配置中并得到密钥已存在的异常。
NHibernate 程序集版本是 3.0.0.4000
对我可能做错的事情有什么建议吗?