2010-10-25 24 views
0

Situation suivante: Il existe un tableau agissant comme crosstable (mergeSet). De plus, il existe un ensemble de valeurs cibles et un ensemble de valeurs source. Les valeurs source peuvent être jointes avec les valeurs cibles via la table croisée. - Mais comment est-il possible d'exprimer une jointure externe de, par exemple, le targetSet par rapport aux autres tables en utilisant une seule expression LINQ?Comment exprimer des jointures externes avec des tables croisées en une seule expression Linq

Actuellement, je trouve que des solutions en utilisant de multiples expressions LINQ (à savoir une jointure de targetSet + mergeSet + sourceSet, le pur gauche partie extérieure et enfin une concaténation du innerJoinResult et outerPart).

 var mergeSet = new[] 
     { 
      new KeyValuePair<int, int>(3, 4), 
      new KeyValuePair<int, int>(5, 6) 
     }; 

     var targetSet = new[] { 1, 3, 5, 7 }; 
     var sourceSet = new[] { 4, 6 }; 

     var innerJoinResult = 
      from mergeItem in mergeSet 
      join sourceItem in sourceSet on mergeItem.Value equals sourceItem 
      join targetItem in targetSet on mergeItem.Key equals targetItem 
      group sourceItem by targetItem; 

     var outerPart = 
      from targetItem in targetSet 
      where !mergeSet.Any(mergeItem => mergeItem.Key == targetItem) 
      group 0 by targetItem; // Fill the right part with zero. 

     var outerJoinResult = outerPart.Concat(innerJoinResult); 

Répondre

2

Le code suivant:

var outerJoinResult = 
     (from ti1 in targetSet 
     join mi1 in mergeSet on ti1 equals mi1.Key into joinedMerge 
     from jm1 in joinedMerge.DefaultIfEmpty() 
     join si1 in sourceSet on jm1.Value equals si1 into joinedSource 
     from js1 in joinedSource.DefaultIfEmpty() 
     select new { target = ti1, source = js1 }).ToList(); 

    outerJoinResult.ForEach(x => Console.Out.WriteLine("Source: {0}, Target: {1}", x.source, x.target)); 

imprimé:

Source: 0, Target: 1 
Source: 4, Target: 3 
Source: 6, Target: 5 
Source: 0, Target: 7 
+0

Merci AntonioR! Ma solution finale a pris fin comme celui-ci (la projection select a été remplacée par une clause de groupe approprié): var = outerJoinResult de TI1 dans targetSet rejoindre mi1 à mergeSet sur TI1 égal mi1.Key dans joinedMerge de jm1 dans joinedMerge.DefaultIfEmpty() joindre si1 dans sourceSet sur jm1.Value est égal à si1 dans joinSource de js1 dans joinSource.DefaultIfEmpty() groupe js1 par ti1; – Nico