web-dev-qa-db-fra.com

LINQ Join avec plusieurs conditions dans la clause On

J'essaie d'implémenter une requête dans LINQ qui utilise une jointure externe gauche avec plusieurs conditions dans la clause ON.

Je vais utiliser l'exemple des deux tables suivantes Project (ProjectID, ProjectName) et Task (TaskID, ProjectID, TaskName, Completed). Je souhaite voir la liste complète de tous les projets avec leurs tâches respectives, mais uniquement les tâches terminées.

Je ne peux pas utiliser de filtre pour Completed == true parce que cela filtrera tous les projets qui n'ont pas de tâches terminées. Au lieu de cela, je veux ajouter Completed == true à la clause ON de la jointure afin que la liste complète des projets soit affichée, mais que seules les tâches terminées soient affichées. Les projets sans tâches terminées afficheront une seule ligne avec une valeur nulle pour la tâche.

Voici le fondement de la requête.

from t1 in Projects
join t2 in Tasks
on new { t1.ProjectID} equals new { t2.ProjectID } into j1
from j2 in j1.DefaultIfEmpty()
select new { t1.ProjectName, t2.TaskName }

Comment puis-je ajouter && t2.Completed == true à la clause on?

Je n'arrive pas à trouver de documentation LINQ sur la façon de procéder.

77
Kuyenda

Il vous suffit de nommer la propriété anonyme de la même manière des deux côtés

on new { t1.ProjectID, SecondProperty = true } equals 
   new { t2.ProjectID, SecondProperty = t2.Completed } into j1

D'après les commentaires de @svick, voici une autre implémentation qui pourrait être plus logique:

from t1 in Projects
from t2 in Tasks.Where(x => t1.ProjectID == x.ProjectID && x.Completed == true)
                .DefaultIfEmpty()
select new { t1.ProjectName, t2.TaskName }
112
Aducci

Ici vous allez avec:

from b in _dbContext.Burden 
join bl in _dbContext.BurdenLookups on
new { Organization_Type = b.Organization_Type_ID, Cost_Type = b.Cost_Type_ID } equals
new { Organization_Type = bl.Organization_Type_ID, Cost_Type = bl.Cost_Type_ID }
31

Vous ne pouvez pas le faire comme ça. La clause join (et la méthode d'extension Join()) ne prend en charge que les équijoins. C'est aussi la raison pour laquelle il utilise equals et non ==. Et même si vous pouviez faire quelque chose comme ça, cela ne marcherait pas, car join est une jointure interne, pas une jointure externe.

1
svick