2010-11-04 10 views
1

j'ai 3 tables dans ma demandeLINQ to Entities - limiter les résultats d'un formulaire de recherche uniquement les résultats qui correspondent à tous les choix pour une relation plusieurs à plusieurs

employé
EMPLOYEEID
EmployeeName
DOB

compétences
SkillID
Description de

EmployeeSkills
EMPLOYEEID
SkillID
YearsExperience

Quelle est la meilleure façon d'écrire une requête LINQ pour permettre à un utilisateur de rechercher simultanément des informations dans le tableau des employés et limiter la résultats à ceux qui correspondent à toutes les compétences choisies? Je n'ai aucun problème quand il s'agit d'une compétence, ou d'une compétence parmi celles choisies, mais je suis coincé sur la façon de revenir seulement quand ils correspondent à tous. Le meilleur que j'ai réussi jusqu'ici est une masse hideuse d'intersections.

Répondre

0

Voici la solution que je suis venu avec l'aide d'une version très simple de votre structure de table:

var q = from e in Employee 
    join es in EmployeeSkills 
    on e.EmployeeID equals es.EmployeeID 
    join s in Skills 
    on es.SkillID equals s.SkillID 
    group s by e into grouping 
    where !skillsToMatch.Except(grouping.Select(x => x.SkillID)).Any() 
    select grouping.Key; 

Où skillsToMatch 'est un IEnumerable de SkillID de vous voulez avoir l'employé. Cela retournera tous les Employés qui ont au moins toutes les compétences dans 'skillsToMatch'.

Si vous avez linqpad installé, vous pouvez voir comment cela fonctionne avec mes données fictives avec ce script:

var Employee = new [] { 
    new { EmployeeID = 1 }, 
    new { EmployeeID = 2 }, 
    new { EmployeeID = 3 }, 
    new { EmployeeID = 4 }, 
    new { EmployeeID = 5 }, 
}; 

var Skills = new [] { 
    new { SkillID = 1 }, 
    new { SkillID = 2 }, 
    new { SkillID = 3 }, 
    new { SkillID = 4 }, 
    new { SkillID = 5 }, 
}; 

var EmployeeSkills = new [] { 
    new { EmployeeID = 1, SkillID = 4 }, 
    new { EmployeeID = 1, SkillID = 5 }, 
    new { EmployeeID = 3, SkillID = 4 }, 
    new { EmployeeID = 3, SkillID = 1 }, 
    new { EmployeeID = 5, SkillID = 3 }, 
}; 

var skillsToMatch = new [] { 4, 5 }; 

var q = from e in Employee 
join es in EmployeeSkills 
on e.EmployeeID equals es.EmployeeID 
join s in Skills 
on es.SkillID equals s.SkillID 
group s by e into grouping 
where !skillsToMatch.Except(grouping.Select(x => x.SkillID)).Any() 
select grouping.Key; 

q.Dump(); 

Jouez en changeant le tableau « skillsToMatch » pour voir si elle fournit le comportement que vous recherchez.

+0

Cela a fait l'affaire. Merci. – Dave

1

Vous pouvez faire une boucle sur les compétences déployées, puis ajouter un Where (x => x.Skills.Contails (skill)) à la requête pour chaque compétence demandée. Cela permettra d'éliminer chaque employé qui n'a pas toutes les compétences.