2

我正在實現LINQ和Nhibernate的「IsLike」擴展,如this post by Fabio中所述。NHibernate的LinqToHql擴展註冊不正確,得到System.NotSupportedException

我的代碼如下所示:

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

什麼,我可能是做錯了什麼建議?

回答

2

搞清楚什麼夏普架構確實和學習更多的關於SessionFactory的(即它不能改變)後,溶液的屬性添加到NHibernateSession.Init呼叫

var configProperties = new Dictionary<string, string> {{ 
    Environment.LinqToHqlGeneratorsRegistry, 
    typeof (MyLinqToHqlGeneratorsRegistry).AssemblyQualifiedName 
}}; 

NHibernateConfiguration = NHibernateSession.Init(
          new SimpleSessionStorage(), 
          GetMappingAssemblies(), null, 
          GetNHibernateConfig(), configProperties, null); 

我嘗試添加屬性到配置文件,但在文件上有驗證錯誤。將它添加到.Init()調用雖然完美。

+0

在SessionExtender中啓動`LinqToHqlGeneratorsRegistry`時,它也可以工作。 – Krzysztof 2012-09-13 21:03:00

0

因爲我知道法比奧的例子工程,它必須是你的包裝類中的東西,我們沒有源代碼。

NHibernateSession.Init做什麼?

什麼時候構建SessionFactory?

+0

NhibernateSession.Init是SharpArchitecture的一部分(http://www.sharparchitecture.net)和AFAIK取會話工廠的照顧。如果我以後需要SessionFactory,那麼可以使用NHibernateSession:NHibernateSession.SessionFactory.OpenSession(); – henriksen 2010-12-22 20:09:34