更好的Linq GroupBy

3
我们正在开发一个广告平台,编写负责服务广告的一个大查询语句,其中有一些服务消费者广告的条件,其中之一是每日预算。所以我们的做法是按个人广告分组获取展示次数和消耗成本,然后再按活动分组,得到以下查询语句:
  (from a in AdCreative
       join h in AdHit on a.ID equals h.AdID into gh
       join l in AdGroup_Location on a.AdGroupID equals l.AdGroupID into gj
       from subloc in gj.DefaultIfEmpty()
       from subhits in gh.DefaultIfEmpty()
       where a.AdDimensionID == 7 && 
             (subloc == null || subloc.LocationID == 23)
       select new {
           ID = a.ID,
           Name = a.Name,
           Spent = (subhits.AdDimension != null) ? ((double)subhits.AdDimension.Credit / 1000 ) : 0,
           CampaignID = a.AdGroup.Campaign.ID,
           CampaignName = a.AdGroup.Campaign.Name,
           CampaignBudget = a.AdGroup.Campaign.DailyBudget

       })
    .GroupBy(adgroup => adgroup.ID)
    .Select(adgroup => new {
        ID = adgroup.Key,
        Name = adgroup.FirstOrDefault().Name,
        Spent = adgroup.Sum(q =>  q.Spent),
        CampaignID = adgroup.FirstOrDefault().CampaignID,
        CampaignName = adgroup.FirstOrDefault().CampaignName,
        CampaignBudget = adgroup.FirstOrDefault().CampaignBudget,
    })
    .GroupBy(q => q.CampaignID)
    .Select(campaigngroup => new {
      CampaignID = campaigngroup.Key,
      DailyBudget = campaigngroup.FirstOrDefault().CampaignBudget,
      Spent = campaigngroup.Sum(q => q.Spent),
      Ads = campaigngroup.GroupBy(q => q.ID).Select(adgroup => new {
        ID = adgroup.Key,
        Name  = adgroup.FirstOrDefault().Name,
        Spent = adgroup.FirstOrDefault().Spent
    })
    })

结果

如您在屏幕截图中看到的那样,它运行良好。然而,当我检查生成的SQL查询时,我得到了402行SQL代码。这是什么情况?有什么我可以做来优化代码吗?


3
LINQ 是为了易用性而构建的,而不是生成简洁查询。 :( - TZHX
a) “how could that be?”的意思是什么? b) “enhance the code”的意思是什么? - AakashM
@AakashM 我的意思是生成的 SQL 查询语句太复杂了,可能有更好的方法用 LINQ 表达它以产生更简单的 SQL 查询。 - Yehia A.Salam
1个回答

0
我唯一注意到的是,在最后一个GroupBy中,您没有聚合,而只显示Key和第一个值。我认为您也可以在那里Select q.Idq.Nameq.Spent
两个GroupBy应该足够,因为您显示了两个级别的聚合(两次Spent)。

很好,现在有243行代码了,我还能做更进一步的优化吗? - Yehia A.Salam
也许可以直接将通过 adgroup.FirstOrDefault() 等选择的项目放入 GroupBy x => new { x.A, x.B, ... } 中。 - Gert Arnold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接