LINQ to SQL doing a Union and Left Outer Join
-
20-08-2019 - |
Question
I have 3 tables. 2 contain lists of files that I need to do a UNION on to get all the unique files, then I want to do a left outer join against the 3rd table to find all the files that are in the 3rd table only and not in the other 2.
To do the UNION I have the following:
var imageUnion = (from img in dc.ImageT1
select img.filename).Union(
from img in dc.ImageT2
select img.filename);
Now, to get the files only in the 3rd table I would do a left outer join as such:
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 };
I understand how to do the left outer join simply against ONE table, but how do I get the result set of my first query into the left outer join? Basically, instead of doing the left outer join against ImagesT1 I want to do it against the imageUnion result.
Thanks!
Solution
You need to select more than one property in your Union; The current result is IEnumerable<string> (assuming your filename is a string).
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 });
Then you should be able to use it in the second query to replace dc.ImageT1.
Though thinking more on it, the Union may not work with 2 anonymous types; To support that, maybe it'd be worth defining a class that has only a Filename and Size?
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 });
OTHER TIPS
You should be able to select from your first query instead of the image table again. Something like:
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 };
edit: You will also to have to edit your imageUnion query to select size as well as filename (and any other columns you need in your final query).