views:

1410

answers:

2

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!

+1  A: 

Hi Larry,

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).

AdamB
That was what I originally tried, but I think because imageUnion result set is an anonymous type it doesn't work. What I mean is when you try to do image.filename in this example, it doesn't have the filename property.
Little Larry Sellers
I'm assuming that you don't want to select the entire img in the first query because the result set would be too large (as in the image is in a blob or something to that effect)?
AdamB
As Chris points out, if you don't want to use your Image class, you could create a scaled down class with just Filename and Size and everything should work as you want it to.
AdamB
+2  A: 

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 });
Chris Shaffer