2

this post by Fabio에 설명 된대로 LINQ 및 Nhibernate에 "IsLike"확장을 구현합니다.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

'LinqToHqlGeneratorsRegistry'가 SessionExtender에서 시작될 때도 작동합니다. – Krzysztof

+0

@Lolo 감사합니다! :) – henriksen

0

Fabio의 예제 으로 작동하므로 래퍼 클래스에 있어야합니다.이 래퍼 클래스에는 소스가 없습니다.

NHibernateSession.Init의 기능은 무엇입니까?

언제 SessionFactory를 구축하고 있습니까?

+0

NhibernateSession.Init은 SharpArchitecture (http://www.sharparchitecture.net)의 일부이며 AFAIK는 SessionFactory를 처리합니다. 나중에 SessionFactory를 원한다면 NHibernateSession을 얻습니다 : NHibernateSession.SessionFactory.OpenSession(); – henriksen

관련 문제