在LINQ to实体中过滤一对多

时间:2019-01-05 12:17:54

标签: c# asp.net-web-api 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#才是。

尝试

这是我刚从网络api方法返回员工时得到的json

[
  {
    "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"
    ]
  }
]

我尝试执行一次selectMany,但是随后我松开了母公司的员工。我试图使用select many的结果选择器重载,但是所需的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。

有帮助吗?

1 个答案:

答案 0 :(得分:1)

您需要的是从每个员工的相应集合中过滤出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();