2

J'ai trouvé plusieurs fois des gens qui me posaient la même question mais il semble que la réponse n'ait jamais été satisfaisante même si cela devrait être plutôt facile (en théorie). Voici ma question:Linq to entities - comment sélectionner des entités avec une condition where sur leur entitycollection?

J'ai une entité appelée "Société" à l'intérieur de laquelle j'ai une entitéCollection "Employés" (un à plusieurs). Je dois récupérer toutes les entreprises et pour chacun d'eux, je ne veux que les employés d'un âge supérieur à 21

J'ai essayé:

Return context.Companies.Include("Employees").Where(c => c.Employees.Where(e => e.Age > 21).Count() > 0) 

Cela ne fonctionne pas comme il me donne tous les employés chaque entreprise s'il y a au moins un au-dessus de 21 (il est en fait le même que .Tout())

J'ai essayé:

Return context.Companies.Include("Employees").Select(c => New Company { 
.Id = c.Id, 
.Employees = c.Employees.Where(Function(e) e.Age > 24) 
}).ToList() 

qui ne fonctionnait pas non plus (bien qu'il aurait été perfe ct), il me donne l'erreur suivante: L'entité ou le type complexe 'MyModel.Company' ne peut pas être construit dans une requête LINQ to Entities.

Comment pouvez-vous sélectionner toutes mes entreprises avec seulement, pour chacune d'entre elles, les employés ayant plus de 21 ans? En ce moment, je sélectionne tout et du côté client, je filtre mes employés mais je n'aime pas cette solution.

Quelqu'un peut-il m'aider?


Merci Morteza Manavi-Parast, ça va faire le travail! Néanmoins, je ne me suis pas convaincu de le faire dans une requête unique qui n'a pas été implémentée dans le framework Entity. C'est une situation relativement courante ... Comme preuve, il y a un certain nombre de questions comme la mienne sur ce forum. Je suis surpris ... Peut-être pour la prochaine version? Pour être clair, j'ai besoin d'une liste d'entreprises car je lie directement le résultat de ma requête à un DataGrid. Pour votre information, lorsque je clique sur une ligne de mon DataGrid (donc en sélectionnant une entreprise), j'ai une deuxième Grille qui est peuplée de ses employés (de plus de 21 ans) provenant de l'entité Collection.

+0

Je suis confus, essayez-vous de retourner une séquence de * entreprises * ou * employés *? Si c'est le cas, qu'est-ce que 'company' a à voir avec votre requête? (puisque vous semblez les récupérer tous) –

+0

Du côté client, j'ai un DataGrid qui est lié à une collection de sociétés qui vient directement de cette requête. – Renaud

Répondre

2

Il n'y a aucun moyen d'avoir un "chargement conditionnel de l'alerte" avec inclure dans LINQ aux entités. Il y a 2 solutions de contournement existent bien.Le premier est Filtered Projection et c'est celui que Justin a suggéré mais qui pourrait ne pas être souhaitable dans toutes les situations car il donne une collection d'objets de type anonyme.

La deuxième façon est appelée Deux requêtes chenillés qui vous donne une collection de types fortement entreprises dont les employés satisfaire à une condition et je crois que ce que vous recherchez. Voici le code correspondant:

var companies = context.Companies.ToList(); 
var employees = context.Employee.Where(e => e.Age > 21); 
foreach (var employee in employees) { 
    companies.Single(c => c.CompanyID == employee.CompanyID).Employees.Add(employee); 
} 

S'il vous plaît jeter un oeil à Conditional Eager Loading pour un autre exemple.

2

Au lieu d'utiliser la société de type, avez-vous essayé de sélectionner un nouveau type anonyme:

Return context.Companies.Include("Employees").Select(c => New With { 
    .Id = c.Id, 
    .Employees = c.Employees.Where(Function(e) e.Age > 24) 
}).ToList() 

(Désolé si la syntaxe est un peu hors, il a été un moment que je l'ai fait les types LINQ/Anonymous dans VB.NET)

+0

Je ne peux pas utiliser le type anonyme car la liste renvoyée est directement liée à une collection de sociétés. J'ai vraiment besoin d'une liste d'entreprises. – Renaud

1

Vous pourriez être trop penser à celui-ci. Si vous avez mappé la relation Société => Employé de manière bidirectionnelle, faites simplement la sélection sur Employé avec la clause where et incluez la société.

Return context.Employee.Include("Company").Where(e => e.Age > 21) 
+0

Tim, j'ai un Datagrid sur le côté client qui est lié au résultat de cette requête. Je liste des entreprises afin de retourner une liste d'employés n'est pas une bonne option. – Renaud

+0

il suffit donc d'ajouter '.Select (emp => emp.Company) .Distinct()' à ce que Tim a suggéré et c'est parti .. – quetzalcoatl