Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anyone reduce these 3 LINQ to SQL statements into one?

Tags:

c#

linq-to-sql

Ok so I am trying to get all the Companies assigned to BOTH courses that exist in a course mapping table.

The course mapping table has 2 FK CourseIDs, that point to two different courses in the same table.

Each course has a bundle, and the companies are assigned to bundles.

I am trying to select all the companies that are assigned to both bundles from both courses.

I have been able to do this (Edit: apparently not, because of the OR, can anyone fix this too?) using 3 different LINQ queries, but I am hoping there is a way to reduce it into one for both brevity and performance:

Bundle vegasBundle = (from cm in db.VegasToPegasusCourseMaps
                                   join c in db.Courses on cm.VegasCourseID equals c.CourseID
                                   join b in db.Bundles on c.BundleID equals b.BundleID
                                   where cm.VPCMapID == CourseMapID
                                   select b).FirstOrDefault();

Bundle pegasusBundle = (from cm in db.VegasToPegasusCourseMaps
                                    join c in db.Courses on cm.PegasusCourseID equals c.CourseID
                                    join b in db.Bundles on c.BundleID equals b.BundleID
                                    where cm.VPCMapID == CourseMapID
                                    select b).FirstOrDefault();

IQueryable<Company> companyAssigned = from cb in db.CompanyBundles
                                      join c in db.Companies on cb.CompanyID equals c.CompanyID
                                      where cb.BundleID == vegasBundle.BundleID || cb.BundleID == pegasusBundle.BundleID
                                      select c;

return companyAssigned.ToList();
like image 754
MetaGuru Avatar asked Nov 15 '11 20:11

MetaGuru


Video Answer


1 Answers

Here's your simplified query:

return (
    from cm in db.VegasToPegasusCourseMaps
      join cv in db.Courses on cm.VegasCourseID equals cv.CourseID
      join bv in db.Bundles on cv.BundleID equals bv.BundleID        // vegasBundle

      join cp in db.Courses on cm.PegasusCourseID equals cp.CourseID
      join bp in db.Bundles on cp.BundleID equals bp.BundleID        // pegasusBundle

    from cb in db.CompanyBundles                                     // OR-Join must be in the where clause
      join c in db.Companies on cb.CompanyID equals c.CompanyID

    where cm.VPCMapID == CourseMapID 
      && (cb.BundleID == bv.BundleID || cb.BundleID == bp.BundleID)
    select c
    ).ToList();

[Update]:

Here's the query that matches your requirements. It will only match companies that match both courses.

return (
    from cm in db.VegasToPegasusCourseMaps

    join cv in db.Courses on cm.VegasCourseID equals cv.CourseID
    join bv in db.Bundles on cv.BundleID equals bv.BundleID        // vegasBundle
    join cbv in db.CompanyBundles on bv.BundleId equals cbv.BundleId
    join cv in db.Companies on cbv.CompanyID equals cv.CompanyID

    join cp in db.Courses on cm.PegasusCourseID equals cp.CourseID
    join bp in db.Bundles on cp.BundleID equals bp.BundleID        // pegasusBundle
    join cbp in db.CompanyBundles on bp.BundleId equals cbp.BundleId
    join cp in db.Companies on cbp.CompanyID equals cp.CompanyID

    where cm.VPCMapID == CourseMapID 
        && cv.CompanyID == cp.CompanyID
    select cv
).ToList();

Another thing: since you have the following relationship: Courses.BundleId => Bundles.BundleId => CompanyBundles.BundleId, you can actually join Courses to CompanyBundles and skip the Bundles join. But SQL probably does this anyway.

like image 103
Scott Rippey Avatar answered Sep 30 '22 01:09

Scott Rippey