LINQ groupby语句带键

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

我有下表:

| 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 

ApponintStatus是一个字节,其中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 | | 

这就是我到目前为止所拥有的。 TheDate是我要查询的月份内的日期(即3月4日通过,应该返回March表)

 var r = from appnt in MyDC.LeadsAppointments where appnt.UserID == TheUserID where (appnt.AppointResolved.Year == TheDate.Year && appnt.AppointResolved.Month == TheDate.Month) || (appnt.AppointSet.Year == TheDate.Year && appnt.AppointSet.Month == TheDate.Month) group appnt by appnt.AppointResolved.Date into daygroups select new ViewMonthlyActivityModel() { ViewDate = (from d in daygroups select daygroups.Key.Date).First(), // Problem here: need to get dates for instances where an appointment is set but none are resolved CountTotalSetOnDay = (from c in daygroups where c.AppointSet.Date == daygroups.Key // Problem here select c.AppointID).Count(), CountAttendedOnDay = (from c in daygroups where c.AppointResolved.Date == daygroups.Key.Date where c.AppointStatus == 2 select c.AppointID).Count(), 

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

现在我用2个查询来运行它,我加入结果:一个查询返回约会集,另一个返回已解决的约会。 但是,我仍然坚持使用一次查询中的一个查询解决方案。

有什么建议?

谢谢。

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

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

 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 to 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), }; 

您正在通过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() } 

这应该为您提供一个列表,其中列出了约会的设定日期,以及每个约会的约会数。

我猜有2个读取查询的解决方案工作得很好,现在就代表。