NHibernate的LinqToHql扩展未正确注册,获取System.NotSupportedException
我正在对LINQ和Nhibernate实现“类似岛”的扩展,如中所述 我有这样的代码:NHibernate的LinqToHql扩展未正确注册,获取System.NotSupportedException,linq,nhibernate,extension-methods,linq-to-nhibernate,sharp-architecture,Linq,Nhibernate,Extension Methods,Linq To Nhibernate,Sharp Architecture,我正在对LINQ和Nhibernate实现“类似岛”的扩展,如中所述 我有这样的代码: public class MyLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry { public MyLinqToHqlGeneratorsRegistry() : base() { RegisterGenerator(ReflectionHelper.GetMethodDefini
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);
}
}
但是当我尝试运行查询时,我得到了一个异常
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
对我可能做错了什么有什么建议吗?因为我知道Fabio的示例是有效的,所以它必须是包装器类中的某个东西,我们没有它的源代码 NHibernateSession.Init做什么
您什么时候构建SessionFactory?在了解了Sharp架构的功能并进一步了解了SessionFactory(即它无法更改)之后,解决方案是将属性添加到NHibernateSession.Init调用中
var configProperties = new Dictionary<string, string> {{
Environment.LinqToHqlGeneratorsRegistry,
typeof (MyLinqToHqlGeneratorsRegistry).AssemblyQualifiedName
}};
NHibernateConfiguration = NHibernateSession.Init(
new SimpleSessionStorage(),
GetMappingAssemblies(), null,
GetNHibernateConfig(), configProperties, null);
var configProperties=新字典{{
Environment.LinqToHqlGeneratorsRegistry,
typeof(MyLinqToHqlGeneratorsRegistry).AssemblyQualifiedName
}};
NHibernateConfiguration=NHibernateSession.Init(
新的SimpleSessionStorage(),
GetMappingAssemblys(),null,
GetNHibernateConfig(),configProperties,null);
我尝试将该属性添加到配置文件中,但该文件出现验证错误。不过,将其添加到.Init()调用中效果很好。NhibernateSession.Init是SharpArchitecture()的一部分,AFAIK负责SessionFactory。如果我以后需要SessionFactory,我可以从NHibernateSession获得它:NHibernateSession.SessionFactory.OpenSession();在SessionXtender中启动
LinqToHqlGeneratorsRegistry
时,它也可以工作。
var configProperties = new Dictionary<string, string> {{
Environment.LinqToHqlGeneratorsRegistry,
typeof (MyLinqToHqlGeneratorsRegistry).AssemblyQualifiedName
}};
NHibernateConfiguration = NHibernateSession.Init(
new SimpleSessionStorage(),
GetMappingAssemblies(), null,
GetNHibernateConfig(), configProperties, null);