C# 带键的LINQ groupby语句

C# 带键的LINQ groupby语句,c#,.net,linq,group-by,C#,.net,Linq,Group By,我的查询语法很好,但输出却不好,这真的很奇怪 我有下表: | AppointID | UserID | AppointSet | AppointResolved | AppointStatus | AppointmentDatetime | 1 | 1 | 3/1/2011 | 3/1/2011 | 1 | 3/15/2011 | 2 | 1 | 3/2/2011 | 3/5/201

我的查询语法很好,但输出却不好,这真的很奇怪

我有下表:

| AppointID | UserID | AppointSet | AppointResolved |  AppointStatus | AppointmentDatetime
|     1     |   1    |  3/1/2011  |   3/1/2011      |      1         |     3/15/2011
|     2     |   1    |  3/2/2011  |   3/5/2011      |      4         |     3/16/2011
|     3     |   1    |  3/2/2011  |   3/11/2011     |      2         |     3/11/2011
|     4     |   1    |  3/3/2011  |   3/7/2011      |      3         |     3/25/2011
ApponNintStatus是一个字节,其中1表示设置,2表示有人出席,3表示重新安排,4表示取消。AppointDatetime是为其设置约会的日期

我想做的是创建以下输出,按天统计活动

|    Date     |   Set   |   Attended   |   Rescheduled   |   Cancelled   |
|  3/1/2011   |    1    |              |                 |               |
|  3/2/2011   |    2    |              |                 |               |
|  3/3/2011   |    1    |              |                 |               |
|  3/5/2011   |         |              |                 |      1        |
|  3/7/2011   |         |      1       |                 |               |
|  3/11/2011  |         |              |        1        |               |
这就是我目前所拥有的。日期是我要查询的月份内的日期(即,通过3月4日并应返回3月表)

问题之一是CountTotalSetOnDay只返回当天设置和解决的计数;另一个问题是ViewDate需要返回所有日期:有些日期没有设置约会,但有参加、重新安排或取消的约会,反之亦然,有些日期设置了约会,但没有解决任何约会

现在,我用两个查询运行它,并加入结果:一个查询返回约会集,另一个返回已解决的约会。然而,我仍然坚持一次读取一个查询的解决方案

有什么建议吗


谢谢。

您正在按AppointResolved.Date分组

因此,对于daygroups中的每个条目,daygroups.Key==AppointResolved.Date和c.AppointSet.Date==daygroups.Key where子句将只提供在约会解析当天设置的所有条目

在我看来,如果你想实现你的既定目标,你必须列出表中任何字段中提到的所有日期,并对它们进行计数

例如,考虑:

var appointmentsTaken = (from appnt in GoyaDC.LeadsAppointments
                         where ... // your filters
                         group appnt by appnt.AppointSet.Date into daysset
                         select { Date = daysset.Key Count = daysset.Count() }

这将为您提供一个约会设置的日期列表,以及每个约会的数量。

您需要使用设置日期和解决日期进行分组。这可以通过添加另一个
from
子句来轻松实现,该子句与日期集进行交叉连接,并按这些日期进行分组

下面的查询基于LINQ to Objects查询。LINQtoSQL不支持这种查询,因此您必须决定是使用在客户机上还是在服务器上运行的查询

const byte statusAttended = 2;
const byte statusRescheduled = 3;
const byte statusCancelled = 4;
var query = from a in MyDC.LeadsAppointments.AsEnumerable()
            from date in new[] { a.AppointSet.Date, a.AppointResolved.Date }
            where a.UserID == TheUserID
               && date.Year == TheDate.Year
               && date.Month == TheDate.Month
            group a by date into g
            orderby g.Key
            let set = g.Distinct().ToList()
            select new ViewMonthlyActivityModel
            {
                ViewDate = g.Key,
                CountTotalSetOnDay =
                    set.Count(a => a.AppointSet.Date == g.Key),
                CountTotalAttendedOnDay =
                    set.Count(a => a.AppointResolved.Date == g.Key
                                && a.AppointStatus == statusAttended),
                CountTotalRescheduledOnDay =
                    set.Count(a => a.AppointResolved.Date == g.Key
                                && a.AppointStatus == statusRescheduled),
                CountTotalCancelledOnDay =
                    set.Count(a => a.AppointResolved.Date == g.Key
                                && a.AppointStatus == statusCancelled),
            };

否则,对于应该工作的完全LINQ到SQL解决方案(不是最干净的),您可以尝试以下方法。也许有更好的方法,但我不知道

const byte statusAttended = 2;
const byte statusRescheduled = 3;
const byte statusCancelled = 4;
var query = from a in MyDC.LeadsAppointments
            let setDate = from aa in MyDC.LeadsAppointments
                          where aa.AppointID == a.AppointID
                          select aa.AppointSet.Date
            let resolvedDate = from aa in MyDC.LeadsAppointments
                               where aa.AppointID == a.AppointID
                               select aa.AppointResolved.Date
            from date in setDate.Concat(resolvedDate)
            where a.UserID == TheUserID
               && date.Year == TheDate.Year
               && date.Month == TheDate.Month
            group a by date into g
            orderby g.Key
            let set = g.Distinct()
            select new ViewMonthlyActivityModel
            {
                ViewDate = g.Key,
                CountTotalSetOnDay =
                    set.Count(a => a.AppointSet.Date == g.Key),
                CountTotalAttendedOnDay =
                    set.Count(a => a.AppointResolved.Date == g.Key
                                && a.AppointStatus == statusAttended),
                CountTotalRescheduledOnDay =
                    set.Count(a => a.AppointResolved.Date == g.Key
                                && a.AppointStatus == statusRescheduled),
                CountTotalCancelledOnDay =
                    set.Count(a => a.AppointResolved.Date == g.Key
                                && a.AppointStatus == statusCancelled),
            };

我猜带有2个读取查询的解决方案可以很好地工作,并且现在就可以使用了

是的,这就是我一直坚持的问题。此外,还有一些情况下,有约会集但没有解决约会。这只是一个示例,向您展示如何从表条目中获取“set”列。如果您对输出表中的每个日期和每个必填字段都执行相同的操作,那么您应该拥有实现目标所需的所有信息。好的,我仍在尝试我测试并重新测试了它,但它没有通过伪数据返回正确的结果。我不知道为什么。@frenchie:这两个有什么不对的?使用示例数据,它与输出相匹配(替换了出席日期和重新安排的日期)。是否有您遗漏的案例?我不知道为什么它不起作用,但当我针对样本数据测试查询的输出时,结果是不同的。例如,在CountTotalSetDay上,我的所有样本数据都被设计为每天显示16个计数,通过这个查询,我每天得到40个计数。我提出的问题很有效。它首先获取所有集合,然后获取所有其他情况,然后将这两种情况与linq到对象查询相结合。是的,它有两个读数,但现在我就不说了。您的代码显示了“let”语句是如何工作的,这在其他方面对我有所帮助。谢谢。@frenchie:您介意发布这些数据和预期结果,并更新您的问题以显示您的完整查询吗?如果可能的话,制作一个我(和其他人)可以直接编译的通用示例。我可以(而且确实)编写符合您的示例的虚拟类,但这是我不愿做的大量工作。我这里的例子适用于你给我们的AFAIK,如果我没有你所有的信息,我就帮不了你;我不能只是在文本框中发布电子表格。没关系,我的问题暂时还没有解决。
const byte statusAttended = 2;
const byte statusRescheduled = 3;
const byte statusCancelled = 4;
var query = from a in MyDC.LeadsAppointments
            let setDate = from aa in MyDC.LeadsAppointments
                          where aa.AppointID == a.AppointID
                          select aa.AppointSet.Date
            let resolvedDate = from aa in MyDC.LeadsAppointments
                               where aa.AppointID == a.AppointID
                               select aa.AppointResolved.Date
            from date in setDate.Concat(resolvedDate)
            where a.UserID == TheUserID
               && date.Year == TheDate.Year
               && date.Month == TheDate.Month
            group a by date into g
            orderby g.Key
            let set = g.Distinct()
            select new ViewMonthlyActivityModel
            {
                ViewDate = g.Key,
                CountTotalSetOnDay =
                    set.Count(a => a.AppointSet.Date == g.Key),
                CountTotalAttendedOnDay =
                    set.Count(a => a.AppointResolved.Date == g.Key
                                && a.AppointStatus == statusAttended),
                CountTotalRescheduledOnDay =
                    set.Count(a => a.AppointResolved.Date == g.Key
                                && a.AppointStatus == statusRescheduled),
                CountTotalCancelledOnDay =
                    set.Count(a => a.AppointResolved.Date == g.Key
                                && a.AppointStatus == statusCancelled),
            };