这是我的示例代码:
let departmentResult =
// Where clause could go here...
.Select(department => new Department()
{
Name = department["Name"].ToString(),
// How can I fill Employees collection rather than replace it with a new list?
Employees = new List<Employee>(employeesResult)
}
).FirstOrDefault()
在这个例子中,我正在使用LINQ预测一个新的Department类。部门有一个Employees(Employee列表)集合,我通过向它传递一个单独的LINQ查询结果(employeesResult)来分配。
这种方法的问题是Department的构造函数为其Employees集合分配了一个事件处理程序。通过向Employees分配一个新的Employee列表,而不是迭代地将Employee对象添加到Employees,它“清除”我的事件处理程序,因为新列表没有分配任何事件处理程序。我可以在Employees的setter中重新添加我的事件处理程序,但现在我必须在两个地方添加事件处理程序。
没有办法做到这一点:
let departmentResult =
// Where clause goes here
.Select(department => new Department()
{
Name = department["Name"].ToString(),
// Possible solution: Subclass List<T> and add an AddMany method? This throws an error, though.
// Error: Employees not found.
Employees.AddMany(employeesResult)
}
).FirstOrDefault()
答案 0 :(得分:2)
如果可以,请添加构造函数参数。毕竟,如果构造函数已经创建了一个空列表并附加了一个事件处理程序,那么它也应该能够创建一个填充列表。
.Select(department => new Department(department["Name"].ToString(), employeesResult))
如果无法添加构造函数参数,则只需定义工厂方法。
.Select(department => CreateDepartment(department["Name"].ToString(), employeesResult))
...
static Department CreateDepartment(string name, IEnumerable<Employee> employees)
{
var department = new Department()
{
Name = name
};
foreach (var employee in employees)
{
department.Employees.Add(employee);
}
return department;
}
您也可以将lambda扩展为代码块,但最好我喜欢将副作用代码放在不同的方法中(如上例所示)。
.Select(department =>
{
var department = new Department()
{
Name = department["Name"].ToString()
};
foreach (var employee in employeesResult)
{
department.Employees.Add(employee);
}
return department;
})
答案 1 :(得分:1)
是的,使用AddRange,
let departmentResult =
// Where clause goes here
.Select(department =>
{
var x = new Department()
{
Name = department["Name"].ToString(),
Employees = department.Employees
}
x.Employees.AddRange(employeesResult);
return x;
}).FirstOrDefault()