我有这些表
public class TaskDetails
{
public string EmployeeName {get; set;}
public decimal EmployeeHours {get; set;}
}
public class Tasks
{
public string TaskName {get; set;}
public List<TaskDetails> TaskList {get; set;}
}
我有一个返回List<Tasks>
的函数。我需要的是创建一个新的列表,该列表将EmployeeName
和 SUM 分组EmployeeHours
TaskName
无关。也就是说,我需要获取每个Employees的TotalHours。怎么做到的?
foreach
获取结果并将其放置到Dictionary<string, decimal>
。该逻辑将检查密钥是否不存在,添加新密钥并分配值,如果密钥存在,则将小数值添加到原始值。但我觉得这里太过分了。我觉得我有一个ForEach - GroupBy - Sum组合。
任何有关如何操作的指示对我都非常有帮助。
答案 0 :(得分:4)
var results = tasks.SelectMany(x => x.Tasks)
.GroupBy(x => x.EmployeeName)
.ToDictionary(g => g.Key, g => g.Sum(x => x.EmployeeHours));
给你Dictionary<string, decimal>
。
要获取列表,只需将ToDictionary
替换为Select
/ ToList
链:
var results = tasks.SelectMany(x => x.Tasks)
.GroupBy(x => x.EmployeeName)
.Select(g => new {
EmployeeName = g.Key,
Sum = g.Sum(x => x.EmployeeHours)
}).ToList();
答案 1 :(得分:3)
SelectMany
会有所帮助。
它会将所有TaskDetail
元素的Task
列表“压扁”为一个IEnumerable<TaskDetail>
var result = listOfTasks.SelectMany(x => x.Tasks)
.GroupBy(m => m.EmployeeName)
.Select(m => new {
empName = m.Key,
hours = m.Sum(x => x.EmployeeHours)
});
答案 2 :(得分:1)
var emplWithHours = allTasks
.SelectMany(t => t.Tasks)
.GroupBy(empl => empl.EmployeeName)
.Select(empl => new
{
EmployeeName = empl.Key,
TotalHours = empl.Sum(hour => hour.EmployeeHours)
}).ToDictionary(i => i.EmployeeName, i => i.TotalHours);
此外,当您的类名和字段名都是Tasks
时,它会产生编译时错误:
Error 1 'Tasks': member names cannot be the same as their enclosing type
我会将您的班级命名为Task
,因为它代表了一项任务。
答案 3 :(得分:1)
我会这样做:
var query =
(
from t in tasks
from td in t.TaskList
group td.EmployeeHours by td.EmployeeName into ghs
select new
{
EmployeeName = ghs.Key,
EmployeeHours = ghs.Sum(),
}
).ToDictionary(x => x.EmployeeName, x => x.EmployeeHours);
我稍微简洁一点的查询就是:
var query =
(
from t in tasks
from td in t.TaskList
group td.EmployeeHours by td.EmployeeName
).ToDictionary(x => x.Key, x => x.Sum());
每个人都有利弊。我认为第一个更明确,但第二个更整洁。