此 NHibernate 5 查询不支持什么?
What is not supported in this NHibernate 5 query?
我正在将 Asp.Net 应用程序的 NHibernate 从 4 更新到 5,并收到一个错误:
'query.ToList()' threw an exception of type 'System.NotSupportedException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233067
HelpLink: null
InnerException: null
Message: "query ( query ( select_from ( from ( range ( . _0 RolePrivileges ) a ) ) ( select a ) ) ( where ( and ( == ( . a AccessTypeName ) ( : p12 ) ) ( or ( == ( : p13 ) true ) ( == ( . ( . param002 Role ) Id ) ( : p14 ) ) ) ) ) )"
Source: "NHibernate"
StackTrace: " at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.GetClassName(IASTNode querySource)\r\n at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.Process(IASTNode tree)\r\n at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process()\r\n at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)\r\n at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)\r\n at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)\r\n at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)\r\n at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query)\r\n at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)\r\n at NHib
ernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)\r\n at Remotion.Linq.QueryableBase`1.GetEnumerator()\r\n at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)"
上面的查询是一个 IQueryable,应用了 Where(Expression>) 链。
我的问题是,在我的案例中,NHibernate 5 究竟不支持什么?它适用于 NHibernate 4。
完整的查询是在一个长函数调用链中构建的,其中在查询中附加了很多 Where() ,我可以找出失败的地方:
var predicateReadPrivilege = PredicateBuilder.Create<Resource>(x =>
x.RType.RolePrivileges.Where(a => a.AccessTypeName == accessLevel).AsQueryable().Where(_ => true).Any());// _predicatePrivilegeOnResourceType).Any());
在上面的代码中,是AsQueryable()在作怪(如你所见,即使它是一个多余的条件),如果我将其删除,则不会导致异常。
enter code here
您可以在 18.3 章的 NHibernate documentation 上找到支持的 linq 查询列表。支持的方法和成员
例如,不支持 DateTime 操作(AddDays、AddYears ...),我必须自定义实现才能使其正常工作。
我在NHibernate(https://github.com/nhibernate/nhibernate-core/issues/2471)中问了同样的问题,确认是bug,解决办法是把AsQueryable从Where后面移到mapped collection中,即解决办法后的新代码是:
var predicateReadPrivilege = PredicateBuilder.Create<Resource>(x =>
x.RType.RolePrivileges.AsQueryable().Where(a => a.AccessTypeName == accessLevel).Where(_predicatePrivilegeOnResourceType).Any());
我正在将 Asp.Net 应用程序的 NHibernate 从 4 更新到 5,并收到一个错误:
'query.ToList()' threw an exception of type 'System.NotSupportedException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233067
HelpLink: null
InnerException: null
Message: "query ( query ( select_from ( from ( range ( . _0 RolePrivileges ) a ) ) ( select a ) ) ( where ( and ( == ( . a AccessTypeName ) ( : p12 ) ) ( or ( == ( : p13 ) true ) ( == ( . ( . param002 Role ) Id ) ( : p14 ) ) ) ) ) )"
Source: "NHibernate"
StackTrace: " at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.GetClassName(IASTNode querySource)\r\n at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.Process(IASTNode tree)\r\n at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process()\r\n at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)\r\n at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)\r\n at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)\r\n at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)\r\n at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query)\r\n at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)\r\n at NHib
ernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)\r\n at Remotion.Linq.QueryableBase`1.GetEnumerator()\r\n at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)"
上面的查询是一个 IQueryable
完整的查询是在一个长函数调用链中构建的,其中在查询中附加了很多 Where() ,我可以找出失败的地方:
var predicateReadPrivilege = PredicateBuilder.Create<Resource>(x =>
x.RType.RolePrivileges.Where(a => a.AccessTypeName == accessLevel).AsQueryable().Where(_ => true).Any());// _predicatePrivilegeOnResourceType).Any());
在上面的代码中,是AsQueryable()在作怪(如你所见,即使它是一个多余的条件),如果我将其删除,则不会导致异常。
enter code here
您可以在 18.3 章的 NHibernate documentation 上找到支持的 linq 查询列表。支持的方法和成员
例如,不支持 DateTime 操作(AddDays、AddYears ...),我必须自定义实现才能使其正常工作。
我在NHibernate(https://github.com/nhibernate/nhibernate-core/issues/2471)中问了同样的问题,确认是bug,解决办法是把AsQueryable从Where后面移到mapped collection中,即解决办法后的新代码是:
var predicateReadPrivilege = PredicateBuilder.Create<Resource>(x =>
x.RType.RolePrivileges.AsQueryable().Where(a => a.AccessTypeName == accessLevel).Where(_predicatePrivilegeOnResourceType).Any());