Question

I'm trying to write a query for a database that will left join a table to a look up table and the results will be returned based on a case statement.

In normal SQL the query would look like this:

SELECT chis_id, chis_detail, cilt.mhcatID, cilt.mhtID, 'TheFileName' =
CASE  
    WHEN cilt.mhcatID IS NOT NULL AND cilt.mhtID IS NOT NULL THEN chis_linked_filename
    END
FROM chis
    LEFT JOIN cilt on cilt.mhcatID = chis.mhcat_id AND cilt.mhtID = chis.mht_id 
WHERE cch_id = 50

chis is the table being queried, cilt is a look-up table and does not contain any foreign key relationships to chis as a result (chis has existing FK's to mht and mhcat tables by the mhtID and mhcatID respectively).

The query will be used to return a list of history updates for a record. If the join to the cilt lookup table is successful this means that the caller of the query will have permission to view the filename of any associated files for the history updates.

Whilst during my research I've found various posts on here relating on how to do case statements and left joins in Linq to Entity queries, I've not been able to work out how to join on two different fields. Is this possible?

Was it helpful?

Solution

You need to join on an anonymous type with matching field names like so:

var query = from x in context.Table1
            join y in context.Table2
            on new { x.Field1, x.Field2 } equals new { y.Field1, y.Field2 }
            select {...};

A full working example using the an extra from instead of a join would look something like this:

var query = from chis in context.Chis
            from clit in context.Clit
                                .Where(x => x.mhcatID = chis.mhcat_id)
                                .Where(x =>  x.mhtID = chis.mht_id)
                                .DefaultIfEmpty()
            select new
            {
              chis.id, 
              chis.detail, 
              cilt.mhcatID, 
              cilt.mhtID,
              TheFileName = (cilt.mhcatID != null && cilt.mhtID != null) ? chis.linked_filename : null
            };

OTHER TIPS

Based on what Aducci suggested, I used a group join and DefaultIsEmpty() to get the results I wanted. For some reason, I couldn't get DefaultIfEmpty() didn't work correctly on its own and the resulting SQL employed an inner join instead of a left.

Here's the final code I used to get the left join working:

var query = (from chis in context.chis
             join cilt in context.cilts on new { MHT = chis.mht_id, MHTCAT = chis.mhcat_id } equals new { MHT = cilt.mhtID, MHTCAT = cilt.mhcatID } into tempCilts
             from tempCilt in tempCilts.DefaultIfEmpty()
             where chis.cch_id == 50
             select new { 
                             chisID = chis.chis_id, 
                             detail = chis.chis_detail, 
                             filename = chis.chis_linked_filename, 
                             TheFileName = (tempCilt.mhcatID != null && tempCilt.mhtID != null ? chis.chis_linked_filename : null), 
                               mhtID = chis.mht_id, 
                               mhtcatID = chis.mhcat_id 
                        }).ToList();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top