如何使用Linq2Sql按日历月和其他变量对查询结果进行分组?

时间:2011-12-07 19:20:13

标签: c# linq-to-sql

我的数据库中有一个结算表,其中包含用户根据系统使用情况所欠的每日应计金额。它还包含收到的付款记录。例如......

BillingID   UserID  Type    Date        Description                 Amount
27298   228 D   11/10/2011 12:00:00 AM  Protection Plan             0.2500
27299   228 D   11/10/2011 12:00:00 AM  Storage Subscription Fee    1.6333
27300   250 D   11/10/2011 12:00:00 AM  Storage Subscription Fee    7.9333
27301   253 D   11/10/2011 12:00:00 AM  Storage Subscription Fee    7.9333
27302   254 D   11/10/2011 12:00:00 AM  Storage Subscription Fee    1.6333
27303   255 D   11/10/2011 12:00:00 AM  Storage Subscription Fee    1.6333
27304   257 D   11/10/2011 12:00:00 AM  Storage Subscription Fee    3.3000
27305   262 D   11/10/2011 12:00:00 AM  Storage Subscription Fee    0.0333
27306   265 D   11/10/2011 12:00:00 AM  Storage Subscription Fee    0.9667
27307   266 D   11/10/2011 12:00:00 AM  Storage Subscription Fee    0.9667
27308   228 D   11/10/2011 12:00:00 AM  Subscription Overage        0.0832
27309   228 D   11/11/2011 12:00:00 AM  Protection Plan             0.2500
27310   228 D   11/11/2011 12:00:00 AM  Storage Subscription Fee    1.6333
27311   250 D   11/11/2011 12:00:00 AM  Storage Subscription Fee    7.9333
27312   253 D   11/11/2011 12:00:00 AM  Storage Subscription Fee    7.9333

上述数据不是真实的,但它代表了我正在使用的内容。我的目标是编写一个Linq to Sql查询,以一种易于理解的方式为用户汇总这些数据。以下是所需输出的示例:

User      Month     Type     Description               Amount
228       November   D       Protection Plan            $10   
228       November   D       Storage Subscription Fee   $49
228       November   D       Subscription Overage        $5
228       November   C       Payment                   ($54)
228       December   D       Protection Plan            $10
...

我已经能够通过以下代码完成我需要的部分内容:

BusinessLogic.cs文件:

 public static IEnumerable<Billing> GetBillingHistory(int userid, DateTime startDate, DateTime endDate)
    {
        SBMData2.SBMDataContext db = new SBMData2.SBMDataContext();

        return from b in db.Billings
               where b.UserID == userid && b.Date >= startDate && b.Date <= endDate
               select

 new Billing();

        }

用户帐户页面的代码:

protected void Page_Load(object sender, EventArgs e)
{
    int userID = foo.Data.User.GetIDFromUserName(HttpContext.Current.User.Identity.Name);
    DateTime endDate = DateTime.Now;
    DateTime startDate = endDate.AddMonths(-3);
    RadGrid2.DataSource = BusinessLogic.GetBillingHistory(userID, startDate, endDate);
    RadGrid2.DataBind();

}

此代码的结果是向用户显示的一个很好的网格,显示该特定用户在过去90天内产生的交易。如何修改我的Linq查询以按日历月份,类型和描述汇总结果,如上面“所需输出”部分所述?我已经在这方面工作了很长时间,我真的很难过。任何帮助或指导将不胜感激。

2 个答案:

答案 0 :(得分:1)

我没有在机器上测试过它。你需要玩。但我觉得它可能会奏效。

var listInfo = (from i in context.Billings
                where i.UsreId== id
                group i by new
                { i.UsreId, i.Type, i.DateTime } into newInfo
                select new 
                {
                   UserId,
                   Month,
                   Type,
                   Description,
                   Total= Amount.Count()

                }).AsEnumerable();

答案 1 :(得分:1)

在Linq中分组是我觉得不容易或显而易见的一件事:

已经测试了(Linqpad是一个很棒的玩具!)

from b in Billings
group b by new { b.UserID, b.Type, Month = b.Date.Value.Month, b.Description } into groupItem
select new 
{
    groupItem.Key.UserID,
    groupItem.Key.Type,
    groupItem.Key.Month,
    groupItem.Key.Description,
    Total = groupItem.Sum (b => b.Amount)
}

将月份编号转换为月份名称以显示是一个实现细节( - :

我看着这个,并认为有可能更优雅地表达它 - 我想我可能在整洁的语法方面缺少一些东西,但是它做了它应该做的事情。