【问题标题】:Linq group by giving incorrect statisticsLinq 组通过提供不正确的统计信息
【发布时间】:2021-06-01 06:27:49
【问题描述】:

我有一个表格,我想从中计算以下状态的统计信息:

预期输出

Active = 12
OnHold = 10
Closed = 14
Filled = 15
Expired = 24

查询 1:

var statistics = (from j in context.Job
                  where j.CompanyID == 100 &&
                  {100,101,102,103, 104 }.Contains(j.StatusID) 
                 (j.ActiveDate == "0001-01-01" ? (j.CreationDate >= fromDate && j.CreationDate <= toDate):
                 (j.ActiveDate >= fromDate && j.fromDate <= today))
                 group j by new
                 {
                    j.StatusID
                 }
                 into g
                 select new
                 {
                    ActiveStats = g.Count(inner => (inner.StatusID == 100)),
                    OnHoldStats = g.Count(inner => (inner.StatusID == 101)),
                 }).FirstOrDefault();

对于上述查询,我​​得到的“ActiveStats”和“OnHoldStats”统计数据不正确。

查询 2:

var statistics = (from j in context.Job
                  where j.CompanyID == 100 &&
                  {100,101,102,103, 104 }.Contains(j.StatusID) 
                 (j.ActiveDate == "0001-01-01" ? (j.CreationDate >= fromDate && j.CreationDate <= toDate):
                 (j.ActiveDate >= fromDate && j.fromDate <= today))
                 group j by 1 into g
                 into g
                 select new
                 {
                    ActiveStats = g.Count(inner => (inner.StatusID == 100)),
                    OnHoldStats = g.Count(inner => (inner.StatusID == 101)),
                 }).FirstOrDefault();

我得到了上述查询的“ActiveStats”和“OnHoldStats”的正确统计数据。

我只是不明白为什么查询 1 的结果不正确,为什么查询 2 正确?

另外,哪个查询在性能方面更高效?

我很想了解这两个查询之间的区别,以及在效率和性能方面我应该选择哪个查询。

【问题讨论】:

  • 哪个 EF 版本?
  • @SvyatoslavDanyliv 它的 6.1.3
  • 尝试用Sum替换CountctiveStats = g.Sum(inner =&gt; (inner.StatusID == 100 ? 1 : 0)
  • @SvyatoslavDanyliv 我也这样做了,但查询 1 的结果仍然不正确
  • 区别在于,通过StatusID 摸索后,SQL Server 将只传递给Count 这个StatusID 的记录。所以你不能计算其他状态。 group by 1 是伪造的分组,它只使用聚合进行单条记录查询。

标签: c# entity-framework linq group-by


【解决方案1】:

根据所需的输出,您必须运行以下查询:

var query = 
    from j in context.Job
    where j.CompanyID == 100 &&
        {100,101,102,103, 104 }.Contains(j.StatusID) 
        (j.ActiveDate == "0001-01-01" ? (j.CreationDate >= fromDate && j.CreationDate <= toDate):
        (j.ActiveDate >= fromDate && j.fromDate <= today))
    group j by new { j.StatusID } into g
    select new
    {
        StatusName = 
             j.Key.StatusID == 100 ? "Active" 
           : j.Key.StatusID == 101 ? "OnHold" 
           : j.Key.StatusID == 102 ? "Closed"
           : j.Key.StatusID == 103 ? "Filled"
           : "Expired",
        Count = g.Count()
    };

var statistics = query.ToList();

【讨论】:

    猜你喜欢
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    相关资源
    最近更新 更多