Come esprimere outer join con il tabellone come una singola espressione Linq
-
26-09-2019 - |
Domanda
A seguito di situazione: Esiste un array qualità Tabellone (mergeSet). Inoltre vi esiste un insieme di valori obiettivo e un insieme di valori di origine. I valori di origine possono essere uniti con i valori di riferimento tramite la crosstable. - Ma come è possibile esprimere un outer join di, per esempio, il targetSet contro le altre tabelle utilizzando una sola espressione LINQ?
Al momento ho trovato solo soluzioni utilizzando LINQ multipla espressioni (cioè un inner join di targetSet + mergeSet + sourceSet, allora il puro sinistra parte esterna ed infine una concatenazione del innerJoinResult e 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);
Soluzione
Il seguente codice:
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));
stampata:
Source: 0, Target: 1
Source: 4, Target: 3
Source: 6, Target: 5
Source: 0, Target: 7