Adhésion LINQ avec plusieurs conditions dans la clause On


93

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

J'utiliserai l'exemple des deux tables suivantes: Project (ProjectID, ProjectName) et Task (TaskID, ProjectID, TaskName, Completed). Je veux 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 == truecar cela filtrera tous les projets qui n'ont pas de tâches terminées. Au lieu de cela, je souhaite ajouter Completed == trueà la clause ON de la jointure afin que la liste complète des projets soit affichée, mais seules les tâches terminées seront affichées. Les projets sans tâche terminée afficheront une seule ligne avec une valeur nulle pour 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à l'article sur?

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


Réponse connexe ici en utilisant la syntaxe Lambda
StuartLC

Réponses:


130

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

Sur la base des commentaires de @svick, voici une autre implémentation qui pourrait avoir plus de sens:

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

2
Cela semble être une manière non évidente de le faire. Je ne suis pas sûr de comprendre ce qu'il est censé faire.
svick

1
@svick - L'utilisation de types anonymes vous permet de rejoindre sur plusieurs critères. Vous devez simplement vous assurer que les noms de propriété correspondent sur les deux types. Vous ne savez pas d'où vient la confusion?
Aducci

La confusion est que cela a vraiment plus de sens que deux égalités jointes par and, pas une égalité d'un objet «bizarre». Et pour prouver mon point, votre code est faux. Pour que cela fonctionne, il faudrait avoir truedu côté gauche et du côté t2.Completedroit.
svick

1
Merci Aducci. J'ai dû changer de côté dans la requête pour obtenir le bon contexte, mais cela a fonctionné. Ce problème est simplifié, et dans mon problème du monde réel, ce n'est pas seulement que SecondProperty est vrai ou faux, SecondProperty est un entier et j'utilise AND SecondProperty IN (123, 456). Je vais passer à ce défi et toute aide que vous pourriez donner serait grandement appréciée.
Kuyenda

@svick - Bonne prise, j'ai changé l'ordre du t2.Completed et la vraie valeur. J'ai ajouté une autre solution qui pourrait être moins étrange pour vous.
Aducci

39

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 }

Cela semble plus compréhensible.
Bijay Yadav

1

Vous ne pouvez pas faire ça comme ça. La joinclause (et la Join()méthode d'extension) ne prend en charge que les équi-jointures. C'est aussi la raison, pourquoi il utilise equalset non ==. Et même si vous pouviez faire quelque chose comme ça, cela ne fonctionnerait pas, car il joins'agit d'une jointure interne et non externe.


La jointure externe n'a pas été demandée, et (voir les autres réponses), évidemment vous le pouvez.
edc65

0

Cela fonctionne bien pour 2 tables. J'ai 3 tables et sur la clause doit lier 2 conditions de 3 tables. Mon code:

from p in _dbContext.Products join pv in _dbContext.ProductVariants on p.ProduktId equals pv.ProduktId join jpr in leftJoinQuery on new {VariantId = pv.Vid, ProductId = p. ProductId = jpr.Prices.ProduktID} dans lj

Mais son erreur d'affichage à ce stade: joindre pv dans _dbContext.ProductVariants sur p.ProduktId est égal à pv.ProduktId

Erreur: le type de l'une des expressions de la clause de jointure est incorrect. L'inférence de type a échoué lors de l'appel à «GroupJoin».

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.