【发布时间】:2021-06-22 14:50:41
【问题描述】:
我正在尝试找到一种方法来删除以 LINQ 选择语句为中心的应用程序中的重复代码。假设我们有现有的表格行,需要针对不同的报告要求进行汇总和分组,所有原始数据仅按天分组,需要按周/月和其他属性分组。
DataRow 是一个示例对象,需要将其分组并转换为对象 ReportTableRow(请注意,这是一个大大简化的对象,但实际对象具有更多属性,因此变得更加突出)。
public class DataRow
{
public DateTime Date { get; set; }
public string AccountNumber { get; set; }
public string MachineNumber { get; set; }
public int TEST { get; set; }
}
public class ReportTableRow
{
public int WeekNumber { get; set; }
public int Month { get; set; }
public string AccountNumber{ get; set; }
public string MachineNumber { get; set; }
public int TEST { get; set; }
public string TEST_TRAFFICLIGHT { get; set; }
}
然后我们创建一个 DataRows 列表:
List<DataRow> reportTable = new List<DataRow>()
{
new DataRow()
{
Date = new DateTime(2021, 06, 14),
AccountNumber = "11111111",
MachineNumber = "00AB2021",
TEST = 2
},
new DataRow()
{
Date = new DateTime(2021, 06, 15),
AccountNumber = "11111111",
MachineNumber = "00AB2021",
TEST = 1
},
new DataRow()
{
Date = new DateTime(2021, 06, 15),
AccountNumber = "11111111",
MachineNumber = "00AB2021",
TEST = 6
},
new DataRow()
{
Date = new DateTime(2021, 06, 16),
AccountNumber = "11111111",
MachineNumber = "00AB2021",
TEST = 4
},
new DataRow()
{
Date = new DateTime(2021, 06, 17),
AccountNumber = "11111111",
MachineNumber = "00AB2021",
TEST = 2
},
new DataRow()
{
Date = new DateTime(2021, 06, 18),
AccountNumber = "11111111",
MachineNumber = "00AB2021",
TEST = 7
},
new DataRow()
{
Date = new DateTime(2021, 06, 19),
AccountNumber = "11111111",
MachineNumber = "00AB2021",
TEST = 2
},
new DataRow()
{
Date = new DateTime(2021, 06, 20),
AccountNumber = "11111111",
MachineNumber = "00AB2021",
TEST = 11
},
new DataRow()
{
Date = new DateTime(2021, 06, 14),
AccountNumber = "22222222",
MachineNumber = "11BC2021",
TEST = 2
},
new DataRow()
{
Date = new DateTime(2021, 06, 15),
AccountNumber = "22222222",
MachineNumber = "11BC2021",
TEST = 1
},
new DataRow()
{
Date = new DateTime(2021, 06, 15),
AccountNumber = "22222222",
MachineNumber = "11BC2021",
TEST = 6
},
new DataRow()
{
Date = new DateTime(2021, 06, 16),
AccountNumber = "22222222",
MachineNumber = "11BC2021",
TEST = 4
},
new DataRow()
{
Date = new DateTime(2021, 06, 17),
AccountNumber = "22222222",
MachineNumber = "11BC2021",
TEST = 2
},
new DataRow()
{
Date = new DateTime(2021, 06, 18),
AccountNumber = "22222222",
MachineNumber = "11BC2021",
TEST = 7
},
new DataRow()
{
Date = new DateTime(2021, 06, 19),
AccountNumber = "22222222",
MachineNumber = "11BC2021",
TEST = 2
},
new DataRow()
{
Date = new DateTime(2021, 06, 20),
AccountNumber = "22222222",
MachineNumber = "11BC2021",
TEST = 11
}
};
因此,如果我们需要“按周”或“按月”分组的数据,那么我们需要在报告中分别返回 WeekNumber 或 Month 编号,分组看起来像这样,其中 GetTrafficLight 方法返回一个字符串值基于TEST总和的值:
switch (aggregate.ToUpper())
{
case "BY WEEK":
reportTable = reportTable
.GroupBy(x => new { x.AccountNumber, WeekNumber = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(x.Date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday) })
.Select(x => new ReportTableRow
{
WeekNumber = x.Key.WeekNumber,
Month = x.Max(y => y.Date).Month,
MachineNumber = x.FirstOrDefault().MachineNumber,
TEST = x.Sum(y => y.TEST),
TEST_TRAFFICLIGHT = GetTrafficLight(x.Sum(y => y.TEST)
})
.ToList();
break;
case "BY MONTH":
reportTable = reportTable
.GroupBy(x => new { x.AccountNumber, x.Date.Month })
.Select(x => new ReportTableRow
{
WeekNumber = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(x.Max(y => y.Date), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday),
Month = x.Key.Month,
MachineNumber = x.FirstOrDefault().MachineNumber,
TEST = x.Sum(y => y.TEST),
TEST_TRAFFICLIGHT = GetTrafficLight(x.Sum(y => y.TEST)
})
.ToList();
break;
}
问题是,无论如何要删除“选择”代码并将其传递给可以接受匿名分组的方法或对象,以便可以多次重复使用。将匿名分组更改为包含两个属性的编译时对象意味着然后在数据集中返回重复项,是否找到一种方法来删除编译时分组成员中的重复项可能有助于解决?
请注意,已创建代码来提出这个问题。
【问题讨论】:
-
我之前做过类似的事情,和这个 SO 帖子的答案非常相似:stackoverflow.com/a/16517768/1188197
-
我去看看,谢谢!
-
看起来是这样的,但似乎很简单,将一个字符串值选择为另一个字符串值,像“Sum”这样的计算以及传入一个外部方法(如“GetTrafficLight”)呢?