在 LINQ to Entities 中过滤一对多

Filtering one to many in LINQ to Entities

我在员工和技能之间有一个简单的一对多

var bob = new Employee
        {
            Name = "Bob",
            Title = "Senior Developer",
            Skills = new Collection<string> { "ASP.NET", "C#", "JavaScript", "SQL", "XML" }
        };

        var sam = new Employee
        {
            Name = "Sam",
            Title = "Developer",
            Skills = new Collection<string> { "ASP.NET", "C#", "Oracle", "XML" }
        };

var employees = new List<Employee> { bob, sam };

目标

我需要除 C# 之外所有具备所有技能的员工。

尝试次数

这是 json 当我 return 员工来自网络 api 方法时得到的

[
  {
    "title": "Senior Developer",
    "name": "Bob",
    "skills": [
      "ASP.NET",
      "C#",
      "JavaScript",
      "SQL",
      "XML"
    ]
  },
  {
    "title": "Developer",
    "name": "Sam",
    "skills": [
      "ASP.NET",
      "C#",
      "Oracle",
      "XML"
    ]
  }
]

我的目标 json 是

[

  {
    "title": "Senior Developer",
    "name": "Bob",
    "skills": [
      "ASP.NET",
      "JavaScript",
      "SQL",
      "XML"
    ]
  },
  {
    "title": "Developer",
    "name": "Sam",
    "skills": [
      "ASP.NET",
      "Oracle",
      "XML"
    ]
  }
]

我已经尝试执行 select许多,但后来我失去了父雇员。我尝试多次使用结果 select 或 select 的重载,但随后所需的 Employee 嵌套在 json.

中丢失

如果我执行这个

var skills = employees
            .SelectMany(e => e.Skills, (e, s) => new { e.Name, s })
            .Where(empAndSkill => !empAndSkill.s.Equals("C#"));

这是我得到的json

[
  {
    "name": "Bob",
    "s": "ASP.NET"
  },
  {
    "name": "Bob",
    "s": "JavaScript"
  },
  {
    "name": "Bob",
    "s": "SQL"
  },
  {
    "name": "Bob",
    "s": "XML"
  },
  {
    "name": "Sam",
    "s": "ASP.NET"
  },
  {
    "name": "Sam",
    "s": "Oracle"
  },
  {
    "name": "Sam",
    "s": "XML"
  }
]

显然不是我想要达到的目标。我的目标看似微不足道,但我尝试的解决方案看起来很复杂,这提醒我也许我遗漏了什么或做错了什么。一个月前我刚刚开始使用 LINQ to Entities。

有什么帮助吗?

您需要从每个员工的相应集合中筛选出 C#。下面我们只是做一个投影,每个员工到一个从她的技能中过滤掉 C# 的新员工。

var employeesWithCSharpFilteredOut = 
           employees.Select(employee => new Employee
           {
               Name = employee.Name,
               Title = employee.Title,
               Skills = employee.Skills
                                .Where(skill => !string.Equals(skill,"C#",StringComparison.InvariantCultureIgnoreCase))
                                .ToList()
           }).ToList();