tags:

views:

683

answers:

4
+1  Q: 

.NET Linq Join

I have 2 tables in SQL.

Table 1 
Step Id
Step Name

Table 2
Profile Id
Step Id
Completed

I would like to return the following results even if there is not match in table 2:

Results
Table1.Step Id
Table1.Step Name
Table2.Profile Id
Table2.Completed

The way I am doing this in SQL is the following:

select * from [Table 1] t1
left join [Table 2] t2
on t1.Step Id = t2.Step Id

This produces the results I expect.

When I translate this into linq:

public static List<UserCompletion> GetStepCompletion(string category, string profileid) { 

List<Step> step = GetSteps(category);
List<UserStep> userStep = GetUserSteps(category, profileId);    

var q = from s in step
         join us in userStep
         on s.Id equals us.StepId
         select new UserCompletion
         {
           StepId = s.Id,
           Headline = s.StepName,
           ProfileId = us.ProfileId
           Completed= us.Completed
          };

     return q.ToList();

}

It works but like a JOIN not a left join. I only get matching results back.

Also, UserCompletion is an object that I return from this method.

I have been banging my head on this for a few days...any help would be appreciated.

+2  A: 

Try something along the lines of the following:

var q = from s in step
        join us in userStep 
        on s.Id equals us.StepId into tmpjoin
        from x in tmpjoin.DefaultIfEmpty()
        select new UserCompletion { ... }
Jakob Christensen
Nicely done. I was wimbling around trying to get syntax right :)
Jon Skeet
Sorry, didn't mean to steal your credits :-)
Jakob Christensen
I tried that but i am getting a nullreference excpetion on the select line. - code belowvar q = from s in step join us in userStep on s.Id equals us.StepId into tmpjoin from x in tmpjoin.DefaultIfEmpty()select new UserStepAccepted {StepId = s.Id, Headline = s.StepName, Completed= x.Completed};
Joshua
A: 

I tried that but i am getting a nullreference excpetion on the select line. - code below

var q = from s in step 
join us in userStep 
on s.Id equals us.StepId 
into tmpjoin from x in tmpjoin.DefaultIfEmpty() 
select new UserStepAccepted {StepId = s.Id, Headline = s.StepName, Completed= x.Completed};
Joshua
+1  A: 

You could also try this (assuming us.Completed is boolean):

var q = from s in step
         let us = (from i in userStep where s.Id = i.StepId).SingleOrDefault()
         select new UserCompletion
         {
           StepId = s.Id,
           Headline = s.StepName,
           ProfileId = us.ProfileId
           Completed = us == null ? false : us.Completed
          };

This won't turn into a join in sql, but a nested select statement something like this:

select 
    StepId, Headline, ProfileId,
    isnull((select top(1) Completed from userStep where StepId = Id), 0) as Completed
from step
jrummell
A: 

Found it.

Seems like I need to add a evaluation on the item that "may" be null.

I added the following to my select

Completed = (x == null) ? String.Empty : x.Completed
Joshua