2

我有以下查询可以正常工作:

var bands = new List<TimeBand>()
            {
                new TimeBand(){Region = 10,PeriodId = 5,StartDate = new DateTime(2013, 04, 01),EndDate = new DateTime(2014, 05, 31),DayName = "Friday",StartTime = "00:00",EndTime = "07:00"},
                new TimeBand(){Region = 10,PeriodId = 5,StartDate = new DateTime(2013, 04, 01),EndDate = new DateTime(2013, 05, 31),DayName = "Friday",StartTime = "07:00",EndTime = "00:00"},
                new TimeBand(){Region = 10,PeriodId = 4,StartDate = new DateTime(2013, 06, 01),EndDate = new DateTime(2013, 08, 31),DayName = "Saturday",StartTime = "20:00",EndTime = "00:00"}
            };

    var query = (from x in bands
                group x by new {x.Region, x.DayName}
                into grp
                    select new TimeBand()
                    {
                        Region = grp.Key.Region,
                        DayName = grp.Key.DayName,
                        StartDate = grp.Min(x => x.StartDate),
                        EndDate = grp.Max(x => x.EndDate)
                    }).ToList();

但是当我按区域和日期名称对结果进行分组时,我没有得到结果中的其他列,即 StartTime 和 EndTime。

如果这是一个 SQL 查询,我会在子查询中使用这个分组结果并获取其他列。

有什么方法可以修改它,所以我还得到了 group by 语句中不包含的属性。

谢谢

4

4 回答 4

1

Just select out the whole group if you want the keys as well as all of the values for all of the items in the groups:

select grp;

The other option is to select out a sequence of all values of the columns that you want from a group:

select new TimeBand()
{
    Region = grp.Key.Region,
    DayName = grp.Key.DayName,
    StartDates = grp.Select(x => x.StartDate),
    EndDates = grp.Select(x => x.EndDate)
}

You'd only need to do this if you didn't want to pull down the data for some number of other columns. If you want all of the columns, just use the first option.

于 2013-11-01T16:51:10.710 回答
1
var query = (from x in bands
                     group x by new { x.Region, x.DayName }
                         into grp
                         select new 
                         {
                             Region = grp.Key.Region,
                             DayName = grp.Key.DayName,
                             MinStartDate = grp.Min(x => x.StartDate),
                             AllStartDates = grp.Select(k => k.StartDate).ToList(),
                             EndDate = grp.Max(x => x.EndDate),
                             AllEndDates = grp.Select(k => k.EndDate).ToList(),
                         }).ToList();
于 2013-11-01T17:10:44.847 回答
1

对源项目进行分组后,您就有了组序列。您将如何规划这些群体取决于您。通常,您在每个组上选择分组键和一些聚合值(这就是 SQL 的工作方式)。但是您可以选择每个组本身,或者每个组中的第一个项目,或者最后一个组项目中的某个值:

from b in bands
group b by new { b.Region, b.DayName } into g
select new {
   g.Key.Region,
   g.Key.DayName,
   StartDate = g.Min(x => x.StartDate),
   EndDate = g.Max(x => x.EndDate),
   AllBandsFromGroup = g,
   FirstBand = g.First(),
   LastBandPeriod = g.Last().Period
}
于 2013-11-01T16:49:00.720 回答
0

您似乎正在尝试查找每个组的最小开始日期时间以及最大结束日期时间。如果您将日期和时间组合到一个属性中,这可能会容易得多。

否则,您将需要一个IComparer<TimeBand>用于开始日期和时间,另一个用于结束日期和时间。

如果您不想组合日期和时间,您可以编写方法来获取组合值:

public DateTime GetStart()
{
    int hour = int.Parse(StartTime.Substring(0, 2));
    int minute = int.Parse(StartTime.Substring(3, 2));

    return new DateTime(StartDate.Year, StartDate.Month, StartDate.Day, hour, minute, 0);
}

public DateTime GetEnd()
{
    int hour = int.Parse(EndTime.Substring(0, 2));
    int minute = int.Parse(EndTime.Substring(3, 2));

    return new DateTime(EndDate.Year, EndDate.Month, EndDate.Day, hour, minute, 0);
}

现在您可以对波段进行分组,并为每个组找到最小开始和最大结束:

var query = from x in bands
            group x by new
                       {
                           x.Region,
                           x.DayName
                       }
            into grp
            select new TimeBand()
                   {
                       Region = grp.Key.Region,
                       DayName = grp.Key.DayName,
                       StartDate = grp.Min(x => x.StartDate),
                       StartTime = grp.Min(x => x.GetStart()).ToShortTimeString(),
                       EndDate = grp.Max(x => x.EndDate),
                       EndTime = grp.Max(x => x.GetEnd()).ToShortTimeString(),
                   };

然而,这不是很优雅。我宁愿首先结合日期和时间。

于 2013-11-01T18:02:03.697 回答