Linq to entity - comment sélectionner des entités avec une condition where sur leur collection d'entités?

eager-loading entitycollection entity-framework linq-to-entities one-to-many

Question

J'ai rencontré plusieurs fois des personnes qui demandaient la même question, mais il semble que la réponse n'ait jamais été satisfaisante, même si cela devrait être assez facile (en théorie). Voici ma question:

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 chacune d’elles, je ne veux que les employés dont l’âge est supérieur à 21 ans.

J'ai essayé :

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

Cela ne fonctionne pas car cela me donne tous les employés pour chaque entreprise s'il y en a au moins un supérieur à 21 (c'est en fait le même que .Any ())

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

Cela n'a pas fonctionné non plus (bien que cela aurait été parfait), 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’elles, les employés ayant plus de 21 ans? Pour le moment, je sélectionne tout et 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 me persuade à peine de le faire dans une requête unique n'a pas été implémenté dans le cadre Entity. Il s’agit d’une situation relativement courante ... Pour le prouver, il existe de nombreuses 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 de sociétés car je lie directement le résultat de ma requête à une grille de données. Pour votre information, lorsque je clique sur une ligne de ma grille de données (afin de sélectionner une entreprise), j'ai une deuxième grille qui contient les employés (âgés de plus de 21 ans) provenant de entityCollection.

Réponse acceptée

Il n’ya aucun moyen d’avoir un "chargement conditionnel conditionnel" avec include dans LINQ to Entities. Il existe cependant deux solutions de contournement. La première est Filtrage Projection et c'est celle que Justin a suggérée, mais qui peut ne pas être souhaitable dans toutes les situations car elle fournit une collection d'objets de type anonyme.

La deuxième méthode s'appelle Two Tracked Queries (Requêtes suivies), qui vous donne un ensemble de types de sociétés extrêmement dynamiques dont les employés remplissent une condition et je pense que c'est ce que vous recherchez. Voici le code pour cela:

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 jetez un oeil à Conditional Eager Loading pour un autre exemple.


Réponse populaire

Au lieu d'utiliser le type Société, 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 décalée, cela fait longtemps que je n'ai pas utilisé LINQ / Anonymous Types dans VB.NET)



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow