使用groupby, sum和count将SQL转换为Linq

本文关键字:SQL 转换 Linq count groupby sum 使用 | 更新日期: 2023-09-27 18:11:03

我想做一个组,并在那求和和计数。我似乎无法在linq中创建解决方案。我如何将我的查询转换为linq?

SELECT HistoricalBillingProductGroup, 
        COUNT(*), 
        BillingPeriod, 
        SUM(TotalMonthlyChargesOtcAndMrc)
FROM [x].[dbo].[tblReport]
group by BillingPeriod, HistoricalBillingProductGroup
order by BillingPeriod

这是我在Linq中得到的

var result =
    context.Reports.GroupBy(x => new {x.BillingPeriod, x.HistoricalBillingProductGroup})
            .Select(x => new StatisticsReportLine
                {
                    HistoricalBillingGroup = x.FirstOrDefault().HistoricalBillingProductGroup,
                    BillingPeriod = x.FirstOrDefault().BillingPeriod,
                    CountOfRows = x.Count(),
                    SumOfAmount = x.Sum(p => p.TotalMonthlyChargesOtcAndMrc) ?? 0
                })
            .ToString();

我从中得到的查询是巨大的,需要很长时间来加载。在SQL中,这是毫秒级的问题。我毫不怀疑这就是解决办法。

使用groupby, sum和count将SQL转换为Linq

我认为对x.FirstOrDefault()的调用是您的问题的根源。其中的每一个都将导致在生成的SQL的SELECT子句中执行非常昂贵的内部查询。

尝试使用IGrouping<T>Key属性:

var result = context.Reports
    .GroupBy(x => new {x.BillingPeriod, x.HistoricalBillingProductGroup})
    .OrderBy(x => x.Key.BillingPeriod)
    .Select(x => new StatisticsReportLine
        {
            HistoricalBillingProductGroup = x.Key.HistoricalBillingProductGroup,
            BillingPeriod = x.Key.BillingPeriod,
            CountOfRows = x.Count(),
            SumOfAmount = x.Sum(p => p.TotalMonthlyChargesOtcAndMrc) ?? 0
        });

或者如果您喜欢查询语法:

var result =
    (from r in context.Reports
     group r by new { r.BillingPeriod, r.HistoricalBillingProductGroup } into g
     orderby g.Key.BillingPeriod
     select new StatisticsReportLine
     {
         HistoricalBillingProductGroup = g.Key.HistoricalBillingProductGroup,
         BillingPeriod = g.Key.BillingPeriod,
         CountOfRows = g.Count(),
         SumOfAmount = x.Sum(p => p.TotalMonthlyChargesOtcAndMrc) ?? 0
     });

你可以试试这个:

var result = context.Reports
                    .GroupBy(x => new {x.BillingPeriod, x.HistoricalBillingProductGroup})
                    .Select(x => new StatisticsReportLine
                    {
                        HistoricalBillingGroup = x.Key.HistoricalBillingProductGroup,
                        BillingPeriod = x.Key.BillingPeriod,
                        CountOfRows = x.Count(),
                        SumOfAmount = x.Sum(p => p.TotalMonthlyChargesOtcAndMrc) ?? 0
                    }).ToString();

在上面的查询中,您通过两个属性BillingPeriodHistoricalBillingProductGroup创建一个组。在每一个要创建的组中,你会有一个键,它将由这两个属性组成。