Linq Query - Multiple Table Selection

Hello.  Let's say we have the tables below:

ID    Name
1      Roadwork

ID           Name    
11           John  
22           Sally
33           Jane
44           Joan          

111           1                  11                1/5/2012
222           1                  22                1/6/2012
333           2                  44                1/9/2012

Each project will have 2 members and each member will sign off on the project.  I need a Linq query that will select a project and also the two project members that have signed off on the project (if any).

The required dataset for this example is below:

1            Roadwork     11                     1/5/2012                 22                   1/6/2012

This dataset will be sent to a dataGrid for display.  At this point, I'm not certain how to select multiple rows from the PROJECTMEMBERS table.  A full query would be appreciated.

Environment:  C#.NET 4.0
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

adskarcoxAuthor Commented:
Note: if there is a better way to do this, than through a single Linq query, I am open to suggestions.
I made a mock-up of the data containers.
The linq generates an ILookup with the project as the key and a key/value pair of the project-member and the signoff objects.
The printing might need a little filtering if the number of members on the project is not as expected.
using System;
using System.Collections.Generic;
using System.Linq;

namespace EE_27633596_CS_CON
   public class CProject
      public int intProjectId { get; set; }
      public string strProjectName { get; set; }
      public override string ToString()
         return intProjectId.ToString() + '-' + strProjectName;

      public override bool Equals(object obj)
         return this.ToString().Equals(((CProject)obj).ToString());

      public override int GetHashCode()
         return this.ToString().GetHashCode();

   public class CProjectMember
      public int intMemberId { get; set; }
      public string strMemberName { get; set; }

   public class CSignOff
      public int intSignOffID { get; set; }
      public int intProjectId { get; set; }
      public int intMemberId { get; set; }
      public DateTime dtSignOffDate { get; set; }

   class Program
      static void Main(string[] args)
         List<CProject> lstProjects = new List<CProject>()
            new CProject(){intProjectId=0, strProjectName="Roadwork"},
            new CProject(){intProjectId=1, strProjectName="Crosswalk"},
            new CProject(){intProjectId=2, strProjectName="WaterMain"}

         List<CProjectMember> lstMembers = new List<CProjectMember>()
            new CProjectMember(){intMemberId=100, strMemberName="Tom"},
            new CProjectMember(){intMemberId=101, strMemberName="Dave"},
            new CProjectMember(){intMemberId=102, strMemberName="Joe"}

         List<CSignOff> lstSignOffs = new List<CSignOff>()
            new CSignOff() {intSignOffID=0, intMemberId=100, intProjectId=0, dtSignOffDate=DateTime.Now},
            new CSignOff() {intSignOffID=1, intMemberId=101, intProjectId=0, dtSignOffDate=DateTime.Now},
            new CSignOff() {intSignOffID=2, intMemberId=100, intProjectId=1, dtSignOffDate=DateTime.Now},
            new CSignOff() {intSignOffID=3, intMemberId=102, intProjectId=1, dtSignOffDate=DateTime.Now},
            new CSignOff() {intSignOffID=4, intMemberId=101, intProjectId=2, dtSignOffDate=DateTime.Now},
            new CSignOff() {intSignOffID=5, intMemberId=102, intProjectId=2, dtSignOffDate=DateTime.Now}

         ILookup<CProject, KeyValuePair<CProjectMember, CSignOff>> lkup =
            from so in lstSignOffs
            join p in lstProjects on so.intProjectId equals p.intProjectId
            join m in lstMembers on so.intMemberId equals m.intMemberId
            select new
               k = p,
               v = new KeyValuePair<CProjectMember, CSignOff>(m, so)
         ).ToLookup(k => k.k, v => v.v);

         foreach (var x in lkup)
            Console.WriteLine("{0}: {1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}",

Open in new window

adskarcoxAuthor Commented:
Why can't this be accomplished with one query?  Or even with a few queries working together?

Almost 100 lines of code to accomplish this seems very excessive.

There has got to be a more efficient way.
adskarcoxAuthor Commented:
I found a way using an IN( ) clause in the linq query.  Inside each IN clause, I put a separate linq query (similar to how it is done in SQL).

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
adskarcoxAuthor Commented:
This resolved my issue.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Query Syntax

From novice to tech pro — start learning today.