【问题标题】:NHibernate - QueryOver criteria appearing in Where instead in Having clause, errorNHibernate - QueryOver 条件出现在 Where 中而不是 Have 子句中,错误
【发布时间】:2015-04-10 15:55:22
【问题描述】:

我在 QueryOver 中使用 Group by 并在 where 子句中有一些标准时遇到问题。想要在 Have 子句中使用 SUM() 值移动一些条件,但每次它出现在 Where 子句中并导致错误。 **Error** ="*An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference*"

Conjunction conjunction = Restrictions.Conjunction();
Conjunction havingconjun = Restrictions.Conjunction();

conjunction.Add<Vendor>(p => v.Name == "Some Vendor");
havingconjun.Add(Restrictions.Gt(
   Projections.Sum(Projections.Property(() => v.Payments),
   Convert.ToDouble(SomeInvoice.Value)));

var reportModels =
            Session.QueryOver<Vendor>(() => v)
    .Where(conjunction)
    .Where(havingconjun)
    .SelectList(list => list
                    .SelectGroup(() => v.Number).WithAlias(() => vModel.VendorNumber)
                    .SelectGroup(() => vtypeCode.Code).WithAlias(() => vModel.VendorType)
                    .SelectGroup(() => v.Name).WithAlias(() => vModel.VendorName))
             .TransformUsing(Transformers.AliasToBean<VendorAnalysisReportModel>())
             .List<VendorAnalysisReportModel>();

预期结果:

SELECT 
    V.VENDORNUMBER, V.VENDORTYPE, V.VENDORNAME, SUM(V.PAYMENTS)
 FROM VENDOR V
    WHERE V.NAME = "Some Vendor"
 GROUP 
    BY V.VENDORNUMBER, V.VENDORTYPE, V.VENDORNAME
 HAVING SUM(V.PAYMENTS) > somevalue

立即行动:

SELECT 
    V.VENDORNUMBER, V.VENDORTYPE, V.VENDORNAME, SUM(V.PAYMENTS)
 FROM VENDOR V
    WHERE V.NAME = "Some Vendor" AND
    SUM(V.PAYMENTS) > somevalue
 GROUP 
    BY V.VENDORNUMBER, V.VENDORTYPE, V.VENDORNAME

【问题讨论】:

  • 请不要出现缺少括号或类似错误。实际查询非常庞大,无法放在这里,因此它是原始问题查询的微小副本。
  • 抱歉忘记了查询中的一行 .Select(Projections.Sum(Projections.Property(() => v.Payments))).WithAlias(() => vModel.Payments) 但我的注意力是关于 Where 和 Have 子句。谢谢
  • 我知道已经有一段时间了,但我遇到了这篇文章,因为我有同样的问题。你能解决吗?
  • 这似乎是一个目前没有解决方案的问题。我用谷歌搜索并尝试了不同的方法,但都没有奏效。
  • 不,但我找到了我公司的其他开发人员也在使用的解决方案,我应该把这个作为答案吗?好的 离开它。我删除了havingconjun表单查询。从 reportmodal 获取答案,然后使用 LINQ 应用我的 where 子句,因为我得到了所有 SUM 字段。

标签: aggregate-functions queryover


【解决方案1】:

好吧,因为很多人在 NHibernate 中找不到这个问题的解决方案,所以我使用了一些简单的技巧来实现我的结果,我可以说解决这个问题,直到 NHibernate 修复它。

在从拥有和运行简单查询中获取删除条件后,它看起来像这样。

var reportModels =
            Session.QueryOver<Vendor>(() => v)
    .Where(conjunction)
    .SelectList(list => list
                    .SelectGroup(() => v.Number).WithAlias(() => vModel.VendorNumber)
                    .SelectGroup(() => vtypeCode.Code).WithAlias(() => vModel.VendorType)
                    .SelectGroup(() => v.Name).WithAlias(() => vModel.VendorName))
             .TransformUsing(Transformers.AliasToBean<VendorAnalysisReportModel>())
             .List<VendorAnalysisReportModel>();

var vlst2 =
                    (from vendrs in reportModels orderby vendrs.VendorName ascending select vendrs)
                        .ToList<VendorAnalysisReportModel>().AsQueryable();

然后您可以在任何字段上放置任意数量的 where 子句。

vlst2 = vlst2.Where(p => p.OutstandingComm > Convert.ToDecimal(toDateComAmount.Value));

vlst2 = vlst2.Where(p => p.ToDateOrders < Convert.ToDecimal(toDateOrdAmount.Value));

我的问题已解决,复杂报表运行成功,我们在其他查询中也遵循同样的方法。

QF

【讨论】:

  • 很抱歉,但这并不能解决问题。您执行查询,使用 QueryOver 获得结果(好),没有任何过滤器(非常糟糕),然后使用 linq 过滤整个结果集(非常非常糟糕)。想象一下在中型数据库中执行此操作,我不是在谈论大型数据库。我想知道这如何能成功解决您复杂的报告问题。
  • 我从来没有说过 Queryover 上没有过滤器,尽可能多的以最小化结果集,然后当 QueryOver 达到限制时,您开始使用 LINQ 进行过滤,我们仔细观察了性能,发现即使使用万条记录。我们还需要注意其他事项,但不在此范围内。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多