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

本文关键字:结果 查询 变量 其他 Linq2Sql 何使用 日历 | 更新日期: 2023-09-27 18:17:10

我的数据库中有一个账单表,其中包含用户根据他们对系统的使用所欠的每日应计金额。它还包含收到的付款记录。例如…

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();
        }

User Account Page的后台代码:

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查询,以便按照日历月份、类型和描述总结结果,就像上面"期望的输出"一节所描述的那样?我研究这个已经很长时间了,我真的很困惑。如有任何帮助或指导,将不胜感激。

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

在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)
}

将月数转换为月名以显示是一个实现细节(-:

我看了看这个,觉得有可能表达得更优雅一些——我想我可能在语法整洁方面遗漏了一些东西,但它做了它应该做的。

我还没有在机器上测试过。你需要玩。但我想它可能会起作用。

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();