【问题标题】:Better Linq GroupByBetter Linq GroupBy
【发布时间】:2012-10-01 00:58:09
【问题描述】:

我们正在开发一个广告平台并编写一个负责投放广告的大型查询,向消费者投放广告有几个标准,其中一个标准是广告系列每日预算,所以我们正在做的是我们按单个广告分组以获取展示次数和消耗的成本,然后按广告系列分组,产生以下查询:

  (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 lines of SQL code。怎么可能?我可以做些什么来增强代码

【问题讨论】:

  • LINQ 是为易于使用而构建的,不会生成简洁的查询。 :(
  • a) “这怎么可能?”是什么意思? b) “增强代码”是什么意思?
  • @AakashM 我的意思是生成的 sql 查询太复杂了,可能有更好的方法在 linq 中表达它以产生更简单的 sql 查询

标签: sql sql-server linq


【解决方案1】:

我唯一注意到的是,在最后一个 GroupBy 中,您不聚合,而只显示 Key 和第一个值。我想你也可以在那里Selectq.Idq.Nameq.Spent

两个GroupBys 就足够了,因为您显示了两个聚合级别(两次Spent)。

【讨论】:

  • 很好,现在有 243 行代码,我还能做进一步优化吗?
  • 也许将adgroup.FirstOrDefault()等选择的项目直接放入GroupBy。 (GroupBy x => new { x.A, x.B, ... })。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多