代码之家  ›  专栏  ›  技术社区  ›  Muhammad Ahmed AbuTalib

在Linq to实体中筛选一对多

  •  1
  • Muhammad Ahmed AbuTalib  · 技术社区  · 7 年前

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

    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一个,他们都有所有的技能。

    尝试

    这是我刚从Web 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的结果选择器重载,但是所需的雇员嵌套在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"
      }
    ]
    

    显然不是我想达到的目标。我的目标看起来微不足道,但我正在尝试的解决方案看起来很复杂,这提醒我,也许我遗漏了什么或做错了什么。一个月前,我刚开始和LinqToEntities打交道。

    有什么帮助吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Christos    7 年前

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