使用LINQ </t> </t>投影新类型时,使用IEnumerable <t>填充列表<t>

时间:2014-09-16 17:44:04

标签: c# linq

这是我的示例代码:

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()

2 个答案:

答案 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()