Кто-нибудь может свести эти 3 оператора LINQ to SQL в одно? - PullRequest
5 голосов
/ 16 ноября 2011

Хорошо, поэтому я пытаюсь получить все Компании, назначенные на ОБА курсы, которые существуют в таблице сопоставления курсов.

Таблица сопоставления курсов имеет 2 идентификатора курса FK, которые указывают на два разных курса в одной таблице.

У каждого курса есть пакет, и компании назначаются для пакетов.

Я пытаюсь выбрать все компании, которые назначены для обоих пакетов, из обоих курсов.

Я смог сделать это (Edit: очевидно, нет, из-за OR, кто-нибудь может это тоже исправить?), Используя 3 разных запроса LINQ, но я надеюсь, что есть способ сократить его в один для краткости и производительности:

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();

Ответы [ 2 ]

3 голосов
/ 16 ноября 2011

Вот ваш упрощенный запрос:

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]

Вот запрос, который соответствует вашим требованиям. Это будет соответствовать только компаниям, которые соответствуют обоим курсам.

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();

Другое дело: поскольку у вас есть следующие отношения: Courses.BundleId => Bundles.BundleId => CompanyBundles.BundleId, вы можете фактически присоединиться Courses к CompanyBundles и пропустить присоединение Bundles. Но SQL, вероятно, делает это в любом случае.

2 голосов
/ 16 ноября 2011

Вот модификация вашего последнего запроса, обеспечивающая получение компаний, зарегистрированных в обоих пакетах:

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

Для объединения запросов вы можете посмотреть ответ Scott Rippey.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...