我正在试图显示一个“周列表”(一周中的每一天),要么显示所有5天(周一至周五),要么显示单个“列表项”(重复列出一周中所有日期的单个列表项)如果所有项目每天都相同(除了密钥)。以下内容有效,直到我将“DayFunctions”(列表)添加为“周列表”的项目。使用List属性进行分组时是否需要执行某些不同的操作?
我无法找到解决此特定分组问题的任何内容,甚至谷歌搜索(几天)。
使用自定义比较器更新
//POCO
public class ScheduleWeek : IScheduleWeek
{
public int Id { get; set; }
public int Yr { get; set; }
public int WeekNo { get; set; }
public List<ScheduleDay> ScheduleDays { get; set; }
}
// POCO
public class ScheduleDay : IScheduleDay
{
public int Id { get; set; }
public int ScheduleWeekId { get; set; }
public string EmpId { get; set; }
public DateTime ScheduleDayDt { get; set; }
public Shift Shift { get; set; }
public Station Station { get; set; }
public List<DayFunction> DayFunctions { get; set; }
}
// POCO
public class DayFunction
{
public int ScheduleDayId { get; set; }
public int FunctionId { get; set; }
}
// HELPER METHOD
public async Task<List<ScheduleDay>> GetScheduleDaysWithDayFunctions(int stationId,
string empId,
int scheduleWeekId)
{
var sdlist = await _ctx.ScheduleDays
.Where(sd => sd.ScheduleDayDt.DayOfWeek != DayOfWeek.Sunday &&
sd.ScheduleDayDt.DayOfWeek != DayOfWeek.Saturday &&
sd.Station.Id == stationId &&
sd.EmpId == empId &&
sd.ScheduleWeekId == scheduleWeekId)
.Include(d => d.DayFunctions)
.ToListAsync();
return sdlist;
}
// HELPER METHOD
// ** ADDED CUSTOM COMPARER
public class ScheduleDayComparer : IEqualityComparer<ScheduleDay>
{
public bool Equals(ScheduleDay x, ScheduleDay y)
{
return x.Id == y.Id && x.DayFunctions
.SequenceEqual(y.DayFunctions);
}
public int GetHashCode(ScheduleDay x)
{
return x.Id.GetHashCode() ^ x.DayFunctions
.Aggregate(0, (a, y) => a ^ y.GetHashCode());
}
}
// MODEL FOR VIEW
public class ScheduleWeekViewModel
{
public ScheduleWeek ScheduleWeek { get; set; }
public ScheduleHelpers ScheduleHelpers { get; set; }
}
// MVC VIEW
@{
var scheduleDayComparer = new ScheduleHelpers.ScheduleDayComparer(); // <-- ADDED
var scheduledays = Model.ScheduleHelpers
.GetScheduleDaysWithDayFunctions(station.Id,
employee.Id.ToString(),
Model.ScheduleWeek.Id).Result
.GroupBy(x => x, scheduleDayComparer) // <-- ADDED
.Select(g => g.First()) // <-- ADDED
.ToList(); // <-- ADDED
//.GroupBy(sd => new
// {
// sd.Shift.Id,
// sd.DayFunctions // <-- this causes the grouping to break
// })
//.Select(g => g.First());
}
<table>
@foreach (var scheduleday in scheduledays)
{
<tr>
<td>
<text>SHIFT: @scheduleday.Shift.Name </text>
</td>
<td>
@foreach (var df in scheduleday.DayFunctions)
{
<text>DAY FUNCTIONS: @df.FunctionId </text>
}
</td>
</tr>
}
</table>
// CONTROLLER ACTION
public async Task<IActionResult> LocationScheduler()
{
var vm = new ScheduleWeekViewModel{};
var user = await _userManager.GetUserAsync(User);
vm.Employees = await _tcomsHelpers.GetEmployeesOfSupervisor(user);
vm.ScheduleDays = await _scheduleHelpers.GetScheduleWeekDaysForScheduler(vm.Employees);
vm.ScheduleWeek = await _scheduleHelpers.GetCurrentScheduleWeek();
vm.ScheduleHelpers = _scheduleHelpers;
return View(vm);
}
答案 0 :(得分:0)
当您在GroupBy
中包含列表属性时,最终会在GroupBy
实施内部进行列表比较,这通常不是您想要的。
您可以解决此问题by implementing a custom IEqualityComparer
,但是您必须为组密钥定义命名类型,因为无法为匿名类型定义IEqualityComparer
。另一种方法是按复合string
键进行分组,如下所示:
.GroupBy(sd => new {
sd.Shift.Id
, string.Join(
"|"
, sd.DayFunctions
.OrderBy(f => f.ScheduleDayId).ThenBy(f => f.FunctionId)
.Select(f => $"{f.ScheduleDayId}:{f.FunctionId}")
)
})