2011-05-10 77 views
4

我有这个对象的列表:如何在一个LINQ中获得两个不同的聚合?

public class Customer 
{ 
    public int Id { get; set; } 
    public string EmailAddress { get; set; } 
    public DateTime ServiceStartDate { get; set; } 
    public DateTime? BillingStartDate { get; set; } 
    public string Status { get; set; } 
} 

在制作图表制剂显示在仪表盘上我试图凝聚这份名单到这个对象的另一个列表:

public class DashboardCustomerConversions 
{ 
    public string Month { get; set; } 
    public int Trials { get; set; } 
    public int Purchased { get; set; } 
} 

凡最终的结果看起来是这样:

Month  Trials Purchases 
--------- ------ --------- 
Dec 2010 390  250 
Jan 2011 345  190 
Feb 2011 576  340 

我有一个很难拿出一个LINQ声明能达到期望的最终结果。这种说法是非常接近:

var list = from b in results 
      group b by new { b.ServiceStartDate.Year, b.ServiceStartDate.Month } into g 
      select new Test 
         { 
          Month = string.Format("{0} {1}", CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(g.Key.Month), g.Key.Year), 
          Trials = g.Count(), 
          Purchased = g.Count() 
         }; 

中最明显的问题是“购买= g.Count()”行,它只是重复的试验结果。我想计算BillingStartDate.HasValue为true的对象。

有没有一种方法来重构LINQ来完成这项工作?

编辑:我宁愿流利的语法风格,但我无法得到上述工作。任何变化的答案都会很好。

回答

3

您需要将条件传递给Count方法。

Purchased = g.Count(q => q.BillingStartDate.HasValue) 
+0

唉!我很亲密。我一直试图通过“b”或“g”知道这是错误的,但无法提出更好的东西。我仍然吮吸lambda。谢谢。 – 2011-05-10 13:36:46

2

所以SLaks有正确的解决方案。这里写的是流利的语法

listOfCustomer.GroupBy(c => new { c.ServiceStartDate.Year, c.ServiceStartDate.Month }) 
       .Select(group => new DashboardCustomerConversions() 
           { 
            Month = string.Format("{0} {1}", CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(group.Key.Month), group.Key.Year), 
            Trials = group.Count(), 
            Purchased = group.Count(c => c.BillingStartDate.HasValue) 
           }); 
相关问题