【问题标题】:How to group by in LINQ?如何在 LINQ 中分组?
【发布时间】:2013-07-30 16:38:30
【问题描述】:

我需要返回特定用户每日约会的最后 30 天,并检查该用户是否每天至少进行了 8 小时的约会。

在 sql 中我可以用这个命令做到这一点:

select IDAppointment,IDUser, SUM(DurationInHours) from Note where AppointmentDate > *lastmonth and IDUser = @userID group by IDUser,IDAppointment,AppointmentDate   

然后我得到结果并验证 DurationInHours(double 类型)。

是否可以使用 LINQ 来实现? 获取上个月用户约会的列表并逐日验证

谢谢!

【问题讨论】:

  • 是的!到目前为止你尝试过什么?
  • Group by in LINQ 的可能重复项
  • @Brian 不过,他有多个密钥。

标签: c# .net linq entity-framework linq-to-sql


【解决方案1】:

这应该是大致存在的,虽然这不在我的脑海中,因为不在 IDE 中。

var result = context.Notes
                    .Where(n => [Your where clause])
                    .GroupBy(n => new { n.IDUser, n.IDAppointment, n.AppointmentDate})
                    .Select(g => new {
                                   g.Key.IDAppointment,
                                   g.Key.IDUser,
                                   g.Sum(n => n.DurationInHours)});

更新:

作为参考,您的 where 子句将是这样的......(再次从我的脑海中浮出水面)

DateTime lastMonth = DateTime.Today.AddMonths(-1);
int userId = 1 // TODO: FIX
var result = context.Notes.Where(n => n.AppointmentDate > lastMonth
                                   && n.IDUser = userId)

导致....

DateTime lastMonth = DateTime.Today.AddMonths(-1);
int userId = 1 // TODO: FIX
var result = context.Notes
                    .Where(n => n.AppointmentDate > lastMonth
                             && n.IDUser = userId)
                    .GroupBy(n => new { n.IDUser, n.IDAppointment, n.AppointmentDate})
                    .Select(g => new {
                                   g.Key.IDAppointment,
                                   g.Key.IDUser,
                                   g.Sum(n => n.DurationInHours)});

【讨论】:

  • 应该注意OP提到的是30 days,而不是1 month,虽然不一样,但是思路是一样的。
  • 它几乎可以工作,但我的存储库默认返回一个 List 。 groupby 方法改变了它的类型。如何将“结果”再次转换为 Note 对象?
  • @ggui 如果您将其转回笔记列表,您将失去分组和总和。您可以通过在总和后添加 Notes = g 将注释添加到匿名结果中。这将使您可以选择组成每个组的注释。
【解决方案2】:

这是我测试过的解决方案。

DateTime lastMonth = DateTime.Today.AddMonths(-1);
int selectedUserId = 2; 

var notes = new List<Note>(
    new Note[] {
        new Note() { 
            AppointmentDate = new DateTime(2013,7,30){}, 
            IDAppointment = 1, IDUser = 1, DurationInHours = 1
        },
        new Note() {
            AppointmentDate = new DateTime(2013,7,30){}, 
            IDAppointment = 1, IDUser = 1, DurationInHours = 2
        },
        new Note() {
            AppointmentDate = new DateTime(2013,7,30){}, 
            IDAppointment = 1, IDUser = 1, DurationInHours = 3
        },
        new Note() {
            AppointmentDate = new DateTime(2013,7,28){}, 
            IDAppointment = 2, IDUser =  2, DurationInHours = 2
        },
        new Note() {
            AppointmentDate = new DateTime(2013,7,28){}, 
            IDAppointment = 2, IDUser =  2, DurationInHours = 3
        },
        new Note() {
            AppointmentDate = new DateTime(2013,7,27){}, 
            IDAppointment = 2, IDUser =  2, DurationI nHours = 4
        },
        new Note() {
            AppointmentDate = new DateTime(2013,7,26){}, 
            IDAppointment = 3, IDUser =  3, DurationInHours = 3
        },
        new Note() {
            AppointmentDate = new DateTime(2013,7,25){}, 
            IDAppointment = 3, IDUser =  3, DurationInHours = 4
        },
        new Note() {
            AppointmentDate = new DateTime(2013,7,24){}, 
            IDAppointment = 3, IDUser =  3, DurationInHours = 5
        }
    }
);

var results = from n in notes
              group n by new {n.IDUser, n.IDAppointment, n.AppointmentDate}
              into g
              where g.Key.AppointmentDate > lastMonth && 
                    g.Key.IDUser == selectedUserId
              select new {
                  g.Key.IDAppointment, 
                  g.Key.IDUser, 
                  TotalHours = g.Sum(n => n.DurationInHours)
              };

需要明确地为 summation 属性指定一个名称(即 TotalHours),否则您会得到 错误 CS0746: Invalid anonymous type member declarator。必须使用成员分配、简单名称或成员访问来声明匿名类型成员。

【讨论】:

  • 这是正确的 matzoi,但我不知道如何使用返回的列表进行验证并向用户发送电子邮件。不过谢谢
  • 如果您要问的是如何将结果转换为 Note 类型的元素,您只需要在 select 子句中适当地构造这些对象。就像这样... var results = from n in notes group n by new {n.IDUser, n.IDAppointment, n.AppointmentDate} 到 g 其中 g.Key.AppointmentDate > lastMonth && g.Key.IDUser == selectedUserId 选择新Note() { IDAppointment = g.Key.IDAppointment, IDUser = g.Key.IDUser, DurationInHours = g.Sum(n => n.DurationInHours) };`
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多