Nhibernate Linq - 选择评价最多的商品

时间:2014-01-06 22:08:18

标签: c# linq nhibernate count

也许这个问题涵盖现有问题,但我仍然无法找到解决方案。

我有2张桌子A和B. B有评级 - 这是非常基本的评级,所以它只保留对用户的引用和对表A中项目的引用。我想从表A中选择评分最高的项目。

所以我尝试了这个:

var innerQuery = from csr in session.Query<Rating>()
                                 group csr by csr.ItemId into scrg
                                 orderby scrg.Count() descending
                                 select scrg.Key;

            var result = from cs in session.Query<Item>() where innerQuery.Contains(cs.Id) select cs;

            return result.Take(maxToReturn).ToList<Item>();

返回 List<Item>

对我来说非常重要

但我有一个例外:

Action: Index Exception: System.NotImplementedException: Cannot use group by with the ContainsResultOperator result operator.
at NHibernate.Linq.GroupBy.AggregatingGroupByRewriter.FlattenSubQuery(QueryModel queryModel, QueryModel subQueryModel)
at NHibernate.Linq.GroupBy.AggregatingGroupByRewriter.ReWrite(QueryModel queryModel)
at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitSubQueryExpression(SubQueryExpression expression)
at ............

任何想法怎么做?

更新

我的Item类与评级无关,我只是在显示项目时计算它,因为它可以被任何人评级(所以应该经常更新),但我可以添加关系,如果它会有帮助吗?

谢谢你们,

2 个答案:

答案 0 :(得分:2)

错误信息实际上很清楚。众所周知,Linq to Nhibernate提供商有一些局限性。这似乎是其中一个局限。

意味着您无法使用.Query

正如在评论中已经提到的那样,通过调用ToList将内部查询放入内存中这应该可行,尽管它可能比仅运行一个查询要慢。

 var innerQuery = (from csr in session.Query<Rating>()
                             group csr by csr.ItemId into scrg
                             orderby scrg.Count() descending
                             select scrg.Key).ToList();

或者您可以尝试使用nhibernate提供的其他查询技术之一。条件API实际上似乎支持包含分组的where子句中的这种子查询。以a look here为例。

答案 1 :(得分:1)

我刚才的解决方案是:

            var innerQuery = (from csr in session.Query<Rating>()
                         group csr by csr.Id into items
                         orderby items.Count()
                         select items.Key).ToList();

            var result = (from cs in session.Query<Item>()
                       where innerQuery.Contains(cs.Id)
                       select cs).ToList<Item>();

如果我发现任何其他解决方案更有效率,我会更新它。如果您有任何更好的解决方案可以完全满足我的需求,请随时添加;)