Search code examples
c#linqsql-to-linq-conversion

SQL query to LINQ (complex for me)


I am a very new to LINQ, I have done simple queries, but I have hit a wall on this one. Could someone help me convert this to LINQ? Joining the table to itself and the counting of records has me hung.

SELECT DISTINCT
     RegionID = O.Region,
     Region = R.Office,
     OfficeCount = (SELECT
          COUNT(officeID)
          FROM OFfice
          WHERE Region = O.region
          AND Type IN (5, 6)
          AND ClosedProduction = 0
          AND OfficeID NOT IN (10, 135, 151)
          AND (OfficeID IN (SELECT DISTINCT
                    OfficeID
                    FROM WR_Data_Work
                    WHERE PhaseID IS NOT NULL)
          OR OfficeID = 154))
     FROM office O
     JOIN Office R
     ON O.Region = R.OfficeID
     JOIN Employee VP
     ON R.VicePresID = VP.EmployeeID
     WHERE O.OfficeID NOT IN (10, 135, 151)
     AND O.Type IN (5, 6)
     AND O.ClosedProduction = 0
     AND (O.OfficeID IN (SELECT DISTINCT
                         OfficeID
                         FROM WR_Data_Work
                         WHERE PhaseID IS NOT NULL)
     OR O.OfficeID = 154)
ORDER BY RegionID
OfficeID    OfficeName  Region
88          Office 1    90
90          Office 2    90
96          Office 3    90
86          Office 4    93
91          Office 5    93
92          Office 6    93
93          Office 7    93
95          Office 8    93

In this case, Office 2 is a regional office for offices 1 and 3, but office 7 is a regional office for 4, 5, 6 and 8.


Solution

  • Here is my try without any ability to test:

    var PhaseOffices = (from w in WR_Data_Work where w.PhaseID != null select w.OfficeID).Distinct();
    var TargetOffices = from O in Office
                        where (O.Type == 5 || O.Type == 6) && O.ClosedProduction == 0 &&
                        (!(new[] { 10, 135, 151 }).Contains(O.OfficeID)) && (PhaseOffices.Contains(O.OfficeID) || O.OfficeID == 154)
                        select O;
    
    var res = (from O in TargetOffices
              join R in Office on O.Region equals R.OfficeID
              //join VP in Employee on R.VicePresID equals VP.EmployeeID = not needed?
              orderby O.Region
              select new {
                  RegionID = O.Region,
                  Region = R.Office,
                  OfficeCount = (from ofc in TargetOffices
                                 where ofc.Region == O.Region
                                 select ofc.OfficeID).Count()
               }).Distinct();
    

    Some LINQ Providers won't handle the local array Contains I used, in which case you'll have to replace it with individual tests like I did with Type.