2017-10-20 60 views
-2

J'ai deux listes: une liste de type Personne et une liste de type profession. Les deux sont liés plusieurs-à-plusieurs. En outre, j'ai une troisième liste avec quelques professions. Je voudrais sélectionner toutes les personnes qui correspondent à toutes les professions dans la troisième liste. Quelle serait l'expression LINQ/Lambda?Tous les articles qui correspondent à tous les mots d'une collection

Merci

+0

Partagez votre code, s'il vous plaît –

+0

S'il vous plaît montrer ce que vous avez essayé? Aussi est-ce une collection de mémoire ou à une base de données. Si ce dernier alors quel cadre? –

+1

Vous n'avez fourni aucun détail ici. Avez-vous essayé de résoudre le problème? Quels résultats as-tu obtenus? Veuillez lire le guide [Comment demander] (https://stackoverflow.com/help/how-to-ask) et mettre à jour votre question. – Brett

Répondre

0

La réponse dépend de la façon dont votre séquence de Persons sont connectés à votre séquence de Professions. Vous parlez de listes, mais aussi de relations plusieurs-à-plusieurs, donc je suppose que vos listes sont en fait des tables dans une base de données relationnelle, avec une table de jointure qui se souvient quelles personnes et professions sont liées.

Si vous utilisez le cadre de l'entité, et que vous avez mis en place le many-to-many relationship correctement vous n'avez pas besoin de la troisième table:

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;} 
} 

C'est tout! Entity Framework reconnaîtra que vous modélisez une relation plusieurs-à-plusieurs et créera la troisième table pour cela. Vous n'avez pas besoin de cette troisième table, accédez simplement à ICollections et entity framework effectuera automatiquement les jointures requises avec la troisième table.

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)) 

Si vous ne l'utilisez Entity Framework, ou les classes ne sont pas mis en place avec le ICollection virtuel, vous devrez faire la jonction entre Persons et Professions vous

En supposant que vous avez un se joindre à la table qui relie vos personnes et professions:

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

premier groupe à chaque personne avec tous ProfessionIds dans le Person_Profession_Table.

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(), 
    }) 

En mots: prenez les deux tables: Personnes et PersonProfessions. De chaque personne prend l'Id, de chaque élément personProfession prend le PersonId, pour chaque personne et toutes les personnes correspondantes. Les professions font un nouvel objet: cet objet contient la Personne correspondante, et tous les ProfessionIds des joinedItems correspondants.

De ces personnes avec leurs ProfessionIds, ne conserver que les personnes qui ont tous ProfessionIds dans votre troisième liste

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); 
0

En supposant que votre List s sont liés par élément contenant List s de l'autre type,

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;