2

Fabioによるこの投稿で概説されているように、LINQとNhibernateに「IsLike」拡張機能を実装しています。

私はそのようなコードを持っています:

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です

私が間違っているかもしれないことへの提案はありますか?

4

2 に答える 2

2

Sharp Architectureが何をするのかを理解し、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()呼び出しに追加すると完全に機能しました。

于 2010-12-23T07:58:21.453 に答える
0

Fabioの例が機能することはわかっているので、ラッパークラスに含まれている必要がありますが、ソースはありません。

NHibernateSession.Initは何をしますか?

SessionFactoryを構築するのはいつですか?

于 2010-12-22T17:08:03.690 に答える