与集合中所有单词匹配的所有项目

时间:2017-10-20 10:35:16

标签: linq

我有两个列表:Person类型列表和类型专业列表。两者都是多对多相关的。 另外,我有一些专业的第三个清单。 我想选择所有符合第三个清单中所有职业的人。 什么是LINQ / Lambda表达式?

由于

2 个答案:

答案 0 :(得分:0)

答案取决于Persons序列与Professions序列的关联方式。

您正在讨论列表,但也涉及多对多关系,因此我假设您的列表实际上是关系数据库中的表,其中的连接表会记住哪些人员与专业相关。

如果您使用实体框架,并且正确设置了many-to-many relationship,那么您不需要第三个表格:

class Person
{
    public int Id {get; set;}
    ... // other properties

    // every Person has zero or more Professions (many-to-many)
    public virtual ICollection<Profession> Professions {get; set;}
}

class Profession
{
    public int Id {get; set;}
    ... // other properties

    // every Profession has zero or more Persons (many-to-many)
    public virtual ICollection<Person> Persons {get; set;}
}

class MyDbContext : DbContext
{
    public DbSet<Person> Persons {get; set;}
    public DbSet<Profession> Professions {get; set;}
}

就是这样!

实体框架将认识到您正在建模多对多关系,并将为其创建第三个表。您不需要第三个表,只需访问ICollections,实体框架将自动执行第三个表所需的连接。

using (var dbContext = new MyDbContext())
{
    IEnumerable<Profession> professionList = ... // the third list

    // Keep only the persons where have exactly all Professions from the profession list
    // do this by checking the Ids of the professions in the list
    IEnumerable<int> professionIds = professions
        .Select(profession => profession.Id)
        .OrderBy(id => id);

    var personsWithProfessions = dbContext.Persons
        // keep only persons that have the same Profession Ids as professionIds
        // first extract the the profession Ids the person has
        .Where(person => person.Professions
             .Select(profession => profession.Id)
             // order this in ascending order
             .OrderBy(id => id)
             // check if equal to professionIds:
             .SequenceEqual(professionIds))

如果您没有使用Entity Framework,或者没有使用虚拟ICollection正确设置类,则您必须自己在PersonsProfessions之间进行联接

假设您有一个加入您的人员和职业的加入表:

class Person_Profession
{
     public int Id {get; set;}
     public int PersonId {get; set;}
     public int ProfessionId {get; set;}
}
IQueryable<Person_Profession> Person_Profession_Table = ...

首先将Person_Profession_Table中所有ProfessionIds的每个人分组。

var personsWithProfessionIds = Persons.GroupJoin(person_profession_table,
   person => person.Id,
   personProfession => personProfession.PersonId,
   person, matchingJoiningItems => new
   {
       Person = person,
       ProfessionIds = matchingJoiningItems
           .Select(matchingJoiningItem => matchingJoiningItem.ProfessionId)
           .OrderBy(id => id)
           .ToList(),
   })

用语言:取两个表:Persons和PersonProfessions。从每个人获取Id,从每个personProfession元素中获取PersonId,为每个人和所有匹配的personProfessions创建一个新对象:该对象包含匹配的Person,以及匹配的joinItems的所有ProfessionIds。

从这些拥有职业的人员中,只保留那些拥有所有职业人员的人员

IEnumerable<int> professionIds = professions
        .Select(profession => profession.Id)
        .OrderBy(id => id);
IEnumerable<Person> matchingPersons = personsWithProfessionIds
    .Where(personWithProfessionId => personWithProfessioinId.ProfessionIds
    .SequenceEqual(professiondIds))
    .Select(personWithProfessionId => perfonWithProfessionId.Person);

答案 1 :(得分:0)

假设您的List与其他类型的成员List相关,

var AllPersons = new List<Person>();
var AllProfessions = new List<Profession>();
var desiredProfessions = new List<Profession>();

var findPersons = from p in AllPersons
                  where p.Professions.Any(pp => desiredProfessions.Contains(pp))
                  select p;