2015-10-13 138 views
0

我想下面的SQL查詢轉換爲LINQ的: -SQL查詢轉換爲LINQ的錯誤

exec('SELECT * FROM (SELECT MAS.EmployeeId, MAS.ENTRY_DATE, IT.InDate 
IN_DATE, OT.InDate OUT_DATE, MAS.SHIFT_CODE, MAS.SHIFT_FLAG, CASE WHEN 
(IT.InDate IS NOT NULL) AND (OT.INDATE IS NOT NULL) THEN CASE WHEN IT.InDate = OT.InDate THEN ''FALSE'' ELSE ''OK'' END ELSE ''FAIL'' END AS VALID FROM (SELECT EmployeeId, Time_Date1 ENTRY_DATE,Time_Field1 SHIFT_CODE, Time_Field2 
SHIFT_FLAG FROM [WWEGG8f9bf41c16].[TO_TempInOutNew] GROUP BY EmployeeId, Time_Date1, Time_Field1, Time_Field2) MAS LEFT JOIN [WWEGG8f9bf41c16].[TO_TempInOutNew] IT ON IT.EmployeeId=MAS.EmployeeId AND 
IT.Time_Date1=MAS.ENTRY_DATE AND IT.InOutFlag=''I'' LEFT JOIN [WWEGG8f9bf41c16].[TO_TempInOutNew] OT ON OT.EmployeeId=MAS.EmployeeId AND OT.Time_Date1=MAS.ENTRY_DATE AND OT.InOutFlag=''O'') MY_IN_OUT') 

所以我做了這個與Linqer的幫助: -

var qry = (from MY_IN_OUT in 
           (
            (from MAS in 
             (
              (from TO_TempInOutNew in listTempInOutNew 
              group TO_TempInOutNew by new 
              { 
               TO_TempInOutNew.EmployeeId, 
               TO_TempInOutNew.Time_Date1, 
               TO_TempInOutNew.Time_Field1, 
               TO_TempInOutNew.Time_Field2 
              } into g 
              select new 
              { 
               g.Key.EmployeeId, 
               ENTRY_DATE = g.Key.Time_Date1, 
               SHIFT_CODE = g.Key.Time_Field1, 
               SHIFT_FLAG = g.Key.Time_Field2 
              })) 
            join IT in listTempInOutNew 
              on new { EmployeeId = Convert.ToInt32(MAS.EmployeeId), Time_Date1 = Convert.ToDateTime(MAS.ENTRY_DATE), InOutFlag = "I" } 
             equals new { IT.EmployeeId, IT.Time_Date1, IT.InOutFlag } into IT_join 
            from IT in IT_join.DefaultIfEmpty() 
            join OT in listTempInOutNew 
              on new { EmployeeId = Convert.ToInt32(MAS.EmployeeId), Time_Date1 = Convert.ToDateTime(MAS.ENTRY_DATE), InOutFlag = "O" } 
             equals new { OT.EmployeeId, OT.Time_Date1, OT.InOutFlag } into OT_join 
            from OT in OT_join.DefaultIfEmpty() 
            select new 
            { 
             EmployeeId = (int?)MAS.EmployeeId, 
             ENTRY_DATE = (DateTime?)MAS.ENTRY_DATE, 
             IN_DATE = (DateTime?)IT.InDate, 
             OUT_DATE = (DateTime?)OT.InDate, 
             MAS.SHIFT_CODE, 
             MAS.SHIFT_FLAG, 
             VALID = 
             IT.InDate != null && 
             OT.InDate != null ? (
             IT.InDate == OT.InDate ? "FALSE" : "OK") : "FAIL" 
            })) 
          select new 
          { 
           MY_IN_OUT.EmployeeId, 
           MY_IN_OUT.ENTRY_DATE, 
           MY_IN_OUT.IN_DATE, 
           MY_IN_OUT.OUT_DATE, 
           MY_IN_OUT.SHIFT_CODE, 
           MY_IN_OUT.SHIFT_FLAG, 
           MY_IN_OUT.VALID 
          }).ToList(); 

它給了我錯誤在位置OUT_DATE = (DateTime?)OT.InDate,。 OT.InDate顯示爲空。這不應該是這樣。

未將對象引用設置爲對象的實例。

關於如何解決這個問題的任何建議?

+1

爲什麼使它複雜化,像這樣的複雜查詢不應該使用linq來實現,請使用ADO來代替。 – Sherlock

+0

如果您獲得允許空值,並且您自定義可空的DateTime對象之後就應該執行驗證。爲什麼不在相關的地方用IF語句來處理你的LINQ?或Where子句過濾如果你不允許空值? –

回答

1

您正在使用左連接,因此對象IT和OT可能爲空。 如下所示替換選擇的零件。

select new 
      { 
     EmployeeId = (int?)MAS.EmployeeId, 
     ENTRY_DATE = (DateTime?)MAS.ENTRY_DATE, 
     IN_DATE = (DateTime?)IT != null ? IT.InDate : null, 
     OUT_DATE = (DateTime?)OT != null ? OT.InDate : null, 
     MAS.SHIFT_CODE, 
     MAS.SHIFT_FLAG, 
     VALID = 
     IT != null && IT.InDate != null && 
     OT != null && OT.InDate != null ? (
     IT.InDate == OT.InDate ? "FALSE" : "OK") : "FAIL" 
      }))