LINQ中的Select嵌套Select

7
我正在尝试查询一个包含员工信息的集合。当我查询该集合时,我想返回一个对象枚举,其中每个对象都有两个字段:

  • 名称
  • 经理名称

(请注意,每个经理也是一个员工!)

现在,这里出现了问题。当我在select中进行select时,每个对象返回的ManagerName字段的值是:

System.Data.Common.Internal.Materialization.CompensatingCollection<string>

以下是查询语句:

var query =
    from e in db.Employees    
    select new
    {
        Name = e.Name,
        ManagerName =
            from em2 in db.Employees
            where (em2.EmployeeID == e.ManagerID)
            select em2.Name
    };

具体来说,当我查看ManagerName的值时,我发现它是一个枚举,产生一个单一的项目。而这个单一的项目是一个包含经理名称的字符串。所以,我认为我很接近答案了。
问题:我该如何更改我的查询,使其返回一个对象的枚举,其中每个对象只有两个字符串字段,NameManagerName

你想要什么结果?现在你手头有什么结果?你的 query 变量是否包含了一对字符串集合? - Maxim Zhukov
现在我有: obj.Name = "MyName"; obj.ManagerName = System.Data.Common.Internal.Materialization.CompensatingCollection并且只有在该对象内部才有"MyManagerName"我想要: obj.Name = "MyName"; obj.ManagerName = "MyManagerName"; - DK ALT
1
你想要得到什么? - Maxim Zhukov
当你说“两个字段”时,是指两个记录吗?目前内部的“select”仅选择单个字段,但对于任何匹配的记录(可能为零或多个),它会选择该字段的枚举。将单个记录上的两个字段更改为单个字段很容易,但如果您要将多个记录合并为单个字段,则可能需要应用更多的逻辑。 - David
2个回答

17

试一试:

var query = from e in db.Employees
            select new
            {
                Name = e.Name,
                ManagerName = db.Employees
                                .Where(x => x.EmployeeID == e.ManagerID)
                                .Select(x => x.Name).SingleOrDefault()
            };

不过,如果你已经正确地将数据库与EF(我想你正在使用它)映射,那么你应该有一个可以利用的导航属性:

var query = from e in db.Employees
            select new
            {
                Name = e.Name,
                ManagerName = e.Manager.Name
            };

它起作用了,但我不得不改为FirstOrDefault,否则我会收到以下错误消息: {"方法'Single'和'SingleOrDefault'只能用作最终查询操作。在这种情况下,请考虑使用方法'FirstOrDefault'。"} - DK ALT
我仍然不明白主题发起人想要什么 :( - Maxim Zhukov
@FSou1:他只是想要每个选定员工的经理姓名。 - Daniel Hilgarth
但是为什么他的查询中没有它呢 =\ 看起来很好。 - Maxim Zhukov
@FSou1:结果是一个只有一个元素的列表。他只需要那个元素(而不是在列表中)。这就是FirstOrDefault或SingleOrDefault存在的原因。 - Daniel Hilgarth

2
看起来自连接应该可以解决问题:
var query = from e in db.Employees
            join m in db.Employees on e.ManagerID equals m.EmployeeID
              select new
              {
                Name = e.Name,
                ManagerName = m.Name
              };

1
我认为你需要在连接条件中使用equals而不是= - Daniel Hilgarth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接