任何人都可以将这3个LINQ to SQL语句减少为一个吗?

时间:2011-11-15 20:52:55

标签: c# linq-to-sql

好的,所以我试图将所有公司分配到课程映射表中的两个课程。

课程映射表有2个FK CourseID,指向同一个表中的两个不同课程。

每个课程都有一个捆绑包,公司被分配到捆绑包。

我正在尝试从两个课程中选择分配给这两个捆绑包的所有公司。

我已经能够做到这一点(编辑:显然不是,因为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 个答案:

答案 0 :(得分:3)

这是您的简化查询:

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

<强> [更新]

这是符合您要求的查询。它只会匹配两个课程相匹配的公司。

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 =&gt; Bundles.BundleId =&gt; CompanyBundles.BundleId,您实际上可以Courses加入CompanyBundles并跳过Bundles加入。但是SQL无论如何都可能这样做。

答案 1 :(得分:2)

以下是对您上次查询的修改,以确保您获得两个捆绑包中注册的公司:

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的答案。