我有三个相关的表格:
Employee(EmployeeId, EmployeeName)
Skill(SkillId, SkillName)
EmployeeSkill(EmployeSkillId, EmployeeId, SkillId)
EmployeSkillId
是一种身份。
数据库中的行如下:
EmployeeId | EmployeeNumber | EmployeeName ---------- | -------------- | ------------ 1 | 10015 | John Doe
SkillId | SkillName ------- | --------- 1 | .NET 2 | SQL 3 | OOD 4 | Leadership
EmployeeSkillId | EmployeeId | SkillId --------------- | ---------- | ------- 1 | 1 | 1 2 | 1 | 2 3 | 1 | 3 4 | 1 | 4
如果我的员工在EmployeSkill
注册了三项技能,我希望能够得到如下结果:
John Doe, "Skill-1, Skill2, Skill-3"
即,将该员工的技能名称连接成一个字符串。
我尝试了以下操作,但它无效。
var query = from emp in Employee.All()
from es in emp.EmployeeSkills
join sk in Skill.All() on es.SkillId equals sk.SkillId
group sk by new {emp.EmployeeName} into g
select new TestEntity
{
Name = g.Key.EmployeeName,
Skills = g.Aggregate(new StringBuilder(),
(sb, grp_row) => sb.Append(grp_row.SkillName))
.ToString()
};
技能名称的汇总列表将返回空白。我怎么能这样做?
答案 0 :(得分:1)
听起来你可以将联接作为选择的一部分:
var query = from emp in Employee.All()
select new TestEntity {
Name = emp.EmployeeName,
Skills = string.Join(", ",
(from es in emp.EmployeeSkills
join sk in Skill.All() on es.SkillId equals sk.SkillId
select sk.SkillName)) };
现在,这将分别为每个人单独进行连接,这不是非常有效。另一种选择是首先建立从技能ID到技能名称的映射:
var skillMap = Skill.All().ToDictionary(sk => sk.SkillId,
sk => sk.SkillName);
然后主要查询很简单:
var query = from emp in Employee.All()
select new TestEntity {
Name = emp.EmployeeName,
Skills = string.Join(", ",
emp.EmployeeSkills.Select(sk => skillMap[sk.SkillId]))};
最终有很多方法可以给这只猫上皮 - 例如,如果你想坚持原来的方法,这仍然是可行的。我会这样做:
var query = from emp in Employee.All()
from es in emp.EmployeeSkills
join sk in Skill.All() on es.SkillId equals sk.SkillId
group sk.SkillName by emp into g
select new TestEntity
{
Name = g.Key.EmployeeName,
Skills = string.Join(", ", g)
};
此时它与原始查询非常相似,当然只使用string.Join
而不是Aggregate
。如果所有这三种方法都带有空技能列表,那么我怀疑你的数据有问题。对我来说,为什么你的第一个查询会“成功”但是有一个空的技能列表并不明显。
编辑:好的,这是一个简短的(-ish)但完整的工作示例:
using System;
using System.Collections.Generic;
using System.Linq;
public class Employee
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public static List<Employee> All { get; set; }
public IEnumerable<EmployeeSkill> EmployeeSkills
{
get
{
return EmployeeSkill.All
.Where(x => x.EmployeeId == EmployeeId);
}
}
}
public class Skill
{
public string SkillName { get; set; }
public int SkillId { get; set; }
public static List<Skill> All { get; set; }
}
public class EmployeeSkill
{
public int SkillId { get; set; }
public int EmployeeId { get; set; }
public static List<EmployeeSkill> All { get; set; }
}
class Test
{
static void Main()
{
Skill.All = new List<Skill>
{
new Skill { SkillName = "C#", SkillId = 1},
new Skill { SkillName = "Java", SkillId = 2},
new Skill { SkillName = "C++", SkillId = 3},
};
Employee.All = new List<Employee>
{
new Employee { EmployeeName = "Fred", EmployeeId = 1 },
new Employee { EmployeeName = "Ginger", EmployeeId = 2 },
};
EmployeeSkill.All = new List<EmployeeSkill>
{
new EmployeeSkill { SkillId = 1, EmployeeId = 1 },
new EmployeeSkill { SkillId = 2, EmployeeId = 1 },
new EmployeeSkill { SkillId = 2, EmployeeId = 2 },
new EmployeeSkill { SkillId = 3, EmployeeId = 2 },
};
var query = from emp in Employee.All
from es in emp.EmployeeSkills
join sk in Skill.All on es.SkillId equals sk.SkillId
group sk.SkillName by emp.EmployeeName into g
select new
{
Name = g.Key,
Skills = string.Join(", ", g)
};
foreach (var result in query)
{
Console.WriteLine(result);
}
}
}
结果:
{ Name = Fred, Skills = C#, Java }
{ Name = Ginger, Skills = Java, C++ }