使用LINQ时如何避免重新创建对象

时间:2013-07-18 12:35:32

标签: c# linq

这是我的数据:

private List<Department> Data
{
    get
    {
        return new List<Department>
        {
            new Department{
                Id = 1, 
                Name = "Tech",
                Employees = new List<Employee>{
                    new Employee{Name = "x", Id = 1 },
                    new Employee{ Name = "y", Id = 2}
                }
            },
            new Department{
                Id = 2,
                Name = "Sales",
                Employees = new List<Employee>{
                    new Employee{Name = "a", Id = 3},
                    new Employee {Name = "b", Id = 4}
                }
            }
        };
    }
}

在这里,我将获得所有员工及其相应部门的清单:

List<Employee> employees = (from department in Departments
                       let d = department
                       from e in d.Employees
                       select new Employee{
                            Id = e.Id,
                            Name = e.Name
                            Department = d
                       }).ToList();

困扰我的是我必须重新创建我的Employee对象才能将相应的部门附加到它。有没有办法可以编写我的LINQ语句,而不必重新创建Employee?

可能有更好的方法来表达这个问题 - 所以请随时让我知道是否存在。

修改 我走这条道路的原因是我通过序列化我的部门存储我的数据:

[
    {
        "Id":1,
        "Name":"Sales",
        "Employees":[{"Id":2,"Name":"x"},{"Id":1,"Name":"y"}]
    },
    {
        "Id":2,
        "Name":"Tech",
        "Employees":[{"Id":3,"Name":"d"},{"Id":4,"Name":"f"}]
    }

]

4 个答案:

答案 0 :(得分:1)

你不应该首先遇到这个问题 - 你应该在最初创建它们时完全构建你的Employee实例,而不是在以后的某个时间 - 如果一个员工需要使用一个部门,你应该添加一个构造函数允许/强制提供它:

public Employee(int id, string name, Department department)
{
   ...
}

答案 1 :(得分:1)

如果您确实真的想要,可以使用let - 子句来产生副作用,因为赋值表达式会返回一个值:

List<Employee> employees = (from department in Departments
                            from e in department.Employees
                            let _ = e.Department = department
                            select e).ToList();

我完全同意BrokenGlass ...

答案 2 :(得分:1)

看起来您想使用LINQ来更新实例。这不是预期用途。使用LINQ查询您想要的实例,然后循环结果以进行更新。 (非嵌套)循环不是邪恶的。

var query = 
  from d in Departments
  from e in d.Employees
  select new { Employee = e, Department = d };

foreach(var x in query)
{
  x.Employee.Department = x.Department;
}

答案 3 :(得分:1)

使用let是多余的,在您的示例查询中无用。

此外, LINQ不是正确的工具。您希望影响要查询的对象的状态(即创建副作用),这通常不建议使用。

通过直接比较,这是您尝试做的更好的选择:

 foreach(var department in Departments)
 foreach(var employee in department.Employees)
     employee.Department = department;

但是,如果可以,则应在将员工添加到部门时执行部门分配,可以使用AddEmployee课程中的Department方法,也可以{{1 property setter