【发布时间】:2018-07-05 13:03:05
【问题描述】:
我希望能够使用 Linq 同时按年/月/周/日以及其他属性对一些数据库结果进行分组。用户应该能够在运行时按年/月/周/日在分组之间切换。典型情况是我有某种 DTO,其中包含 DateTime 时间戳以及其他属性。
更新:我找到了一个可行的解决方案。请参阅下面的帖子。
对于仅按日期分组(不包括按其他属性分组),我创建了一个DateGroupKey 类和一个扩展方法:
DateGroupKey 类
public class DateGroupKey
{
public int Year { get; set; }
public int Month { get; set; }
public int Week { get; set; }
public int Day { get; set; }
}
扩展方法
public static IEnumerable<IGrouping<DateGroupKey, TValue>> GroupByDate<TValue>(
this IEnumerable<TValue> source,
Func<TValue, DateTime> dateSelector,
DateGroupType dateGroupType)
{
Func<TValue, DateGroupKey> keySelector = null;
switch (dateGroupType)
{
case DateGroupType.Year:
keySelector = val => new DateGroupKey { Year = dateSelector(val).Year };
break;
case DateGroupType.Month:
keySelector = val => new DateGroupKey { Year = dateSelector(val).Year, Month = dateSelector(val).Month };
break;
case DateGroupType.Week:
keySelector = val => new DateGroupKey { Year = dateSelector(val).Year, Week = dateSelector(val).GetIso8601WeekOfYear() };
break;
case DateGroupType.Day:
keySelector = val => new DateGroupKey { Year = dateSelector(val).Year, Month = dateSelector(val).Month, Day = dateSelector(val).Day };
break;
default:
throw new NotSupportedException($"Group type not supported: {dateGroupType}");
}
return source.GroupBy(keySelector, new DateGroupKeyComparer());
}
DateGroupKeyComparer 是一个实现IEqualityComparer<DateGroupKey> 的类。我可以像这样使用扩展方法:
var grouped = results.GroupByDate<ProductDto>(x => x.TimeStamp, DateGroupType.Month)
它应该可以正常工作。现在,我想扩展这个想法,不仅可以按日期分组,还可以同时按其他一些字段分组。假设ProductDtoclass 具有以下签名
public class ProductDto
{
public DateTime TimeStamp {get; set;}
public int ProductGroup {get; set;}
public int Variant {get; set;}
public double Value {get; set;}
}
我想做一些类似的事情
var grouped = results.GroupByDate<ProductDto>(x => x.TimeStamp, x => x.ProductGroup, x => x.Variant, DateGroupType.Month);
但我似乎无法解决如何解决这个问题。我想过将DateGroupKey抽象成一个IDateGroupKey接口,包含Year、Month、Week和Day属性,并以某种方式告诉GroupBy扩展如何映射到这个特定的实现,但我不确定它是否正确(或 simplay 'a') 方法。
关于如何解决这个问题有什么好的想法吗?
【问题讨论】:
-
这样的东西是否不符合您的需求(伪代码):
results.GroupBy(x => x.Date).ThenBy(x => x.ProductGroup).ThenBy(x => x.Variant)看看documentation。 -
对我来说,这看起来像纯粹的XY problem
-
这与订购有关 - 不是分组?还是我错过了什么:)