Самая простая вещь, которую я мог бы сделать, - это создать конструктор PrintJobByDepartmenReportItem
, который принимает один параметр IEnumerable<IGrouping<string, PrintJob>>
(который, я считаю, должен быть типом переменной g
в вашем примере). Имейте в виду, что для этого также требуется определение конструктора без параметров, и ваши унаследованные классы также должны будут реализовать прототип конструктора для вызова конструктора базового класса с параметром:
Конструктор
public PrintJobReportItem()
{
}
public PrintJobReportItem(IEnumerable<IGrouping<string, PrintJob>> g)
{
this.TotalPagesPrinted = g.Sum(i => i.GetEnumerator().Current.PagesPrinted);
this.AveragePagesPrinted = g.Average(i => i.GetEnumerator().Current.PagesPrinted);
this.PercentOfSinglePagePrintJobs = g.Count(i => i.GetEnumerator().Current.PagesPrinted == 1) * 100 / g.Count(i => i.GetEnumerator().Current.PagesPrinted > 1);
}
Унаследованный конструктор
public PrintJobByDepartmentReportItem(IEnumerable<IGrouping<string, PrintJob>> g) : base(g)
{
this.DepartmentName = g.First().Key;
this.NumberOfUsers = g.Select(i => i.GetEnumerator().Current.UserName).Distinct().Count();
}
Запросы
var q1 = repo.GetQuery<PrintJob>()
.GroupBy(pj => pj.UserName)
.Select(g => new PrintJobByUserReportItem(g));
var q2 = repo.GetQuery<PrintJob>()
.GroupBy(pj => pj.Department)
.Select(g => new PrintJobByDepartmentReportItem(g));
Это имеет один недостаток, предполагая, что вы всегда будете группировать по строковому члену, но вы можете предположительно GroupBy(i => i.MyProperty.ToString())
, когда это уместно, или, возможно, изменить прототип для принятия IEnumerable<IGrouping<object, PrintJob>>
.