LINQ to SQL faisant une union et une jointure externe gauche
-
20-08-2019 - |
Question
J'ai 3 tables. 2 contiennent des listes de fichiers sur lesquels j'ai besoin de faire une UNION pour obtenir tous les fichiers uniques, alors je veux faire une jointure externe gauche contre la 3ème table pour trouver tous les fichiers qui ne figurent que dans la 3ème table et pas dans l'autre 2.
Pour faire l’UNION, j’ai le texte suivant:
var imageUnion = (from img in dc.ImageT1
select img.filename).Union(
from img in dc.ImageT2
select img.filename);
Maintenant, pour obtenir les fichiers uniquement dans la 3ème table, je ferais une jointure externe gauche en tant que telle:
var query = from image in dc.ImageT1
join active in dc.ActiveImages on image.filename equals
active.filename into gj
from subimage in gj.DefaultIfEmpty()
where subimage.filename == null
select new { image.filename, image.size };
Je comprends comment faire la jointure externe gauche simplement contre ONE table, mais comment puis-je obtenir le résultat de ma première requête dans la jointure externe gauche? En gros, au lieu de faire la jointure externe gauche contre ImagesT1, je veux le faire contre le résultat de imageUnion.
Merci!
La solution
Vous devez sélectionner plusieurs propriétés dans votre Union. Le résultat actuel est IEnumerable & Lt; string & Gt; (en supposant que votre nom de fichier est une chaîne).
var imageUnion = (from img in dc.ImageT1
select new { Filename = img.filename, Size = img.size }).Union(
from img in dc.ImageT2
select new { Filename = img.filename, Size = img.size });
Ensuite, vous devriez pouvoir l'utiliser dans la deuxième requête pour remplacer dc.ImageT1.
Bien que l’on réfléchisse davantage, l’Union peut ne pas fonctionner avec 2 types anonymes; Pour supporter cela, peut-être vaudrait-il la peine de définir une classe qui ne possède qu'un nom de fichier et une taille?
public class TempImage
{
public string Filename { get; set; }
public int Size { get; set; }
}
var imageUnion = (from img in dc.ImageT1
select new TempImage() { Filename = img.filename, Size = img.size }).Union(
from img in dc.ImageT2
select new TempImage() { Filename = img.filename, Size = img.size });
Autres conseils
Vous devriez pouvoir sélectionner à nouveau dans votre première requête plutôt que dans la table des images. Quelque chose comme:
var query = from image in imageUnion
join active in dc.ActiveImages on image.filename equals
active.filename into gj
from subimage in gj.DefaultIfEmpty()
where subimage.filename == null
select new { image.filename, image.size };
modifier: vous devrez également modifier votre requête imageUnion pour sélectionner la taille, ainsi que le nom du fichier (et les autres colonnes dont vous avez besoin dans votre requête finale).