Nhibernate 3 Linq抛出Antlr.Runtime.NoViableAltException

时间:2011-04-13 10:52:23

标签: c# linq nhibernate

使用NHibernate 3 linq提供程序我想选择项目子项的最大数量。

使用以下linq查询,我得到一个Antlr.Runtime.NoViableAltException,然后是Antlr.Runtime.MismatchedTreeNodeException

int maxCount = _repository.FindAll<Device>().Max(d=>d.DeviceSensors.Count());

存储库函数FindAll()返回session.Query。

例外详情:

Antlr.Runtime.NoViableAltException occurred
  Message="Exception of type 'Antlr.Runtime.NoViableAltException' was thrown."
  Source="NHibernate"
  Char=0
  CharPositionInLine=-1
  Index=21
  Line=0
  UnexpectedType=84
  StackTrace:
       at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.aggregateExpr() in d:\CSharp\NH\nhibernate\src\NHibernate\Hql\Ast\ANTLR\Generated\HqlSqlWalker.cs:line 3203
  InnerException: 

Antlr.Runtime.MismatchedTreeNodeException occurred
  Message="Exception of type 'Antlr.Runtime.MismatchedTreeNodeException' was thrown."
  Source="Antlr3.Runtime"
  Char=0
  CharPositionInLine=-1
  Index=21
  Line=0
  UnexpectedType=84
  StackTrace:
       at Antlr.Runtime.Tree.TreeParser.RecoverFromMismatchedToken(IIntStream input, Int32 ttype, BitSet follow)
       at Antlr.Runtime.BaseRecognizer.Match(IIntStream input, Int32 ttype, BitSet follow)
       at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.functionCall() in d:\CSharp\NH\nhibernate\src\NHibernate\Hql\Ast\ANTLR\Generated\HqlSqlWalker.cs:line 7906
  InnerException:

 NHibernate.Hql.Ast.ANTLR.QuerySyntaxException: Exception of type 'Antlr.Runtime.NoViableAltException' was thrown. [.First(.Select(.OrderByDescending(NHibernate.Linq.NhQueryable`1[RGB.TTT.Domain.Device], Quote((x, ) => (x.DeviceSensors.Count)), ), Quote((x, ) => (new <>f__AnonymousType2`1(x.DeviceSensors.Count, ))), ), )]

这是一个已知问题吗?或者我必须重写查询,欢迎任何建议。

1 个答案:

答案 0 :(得分:2)

显然,当前的NHibernate Linq提供程序无法在Select子句中组合Max()和内部Select。您可能需要将Max拉出查询并在之后应用它,例如

int maxCount = session.Query<Device>()
    .Select(d => d.DeviceSensors.Count)
    .ToList()
    .Max();

没有子选择的简单版本有效:

int maxCount = session.Query<Device>()
    .Select(d => d.Name.Length)
    .Max();