2014-03-13 64 views
1

我試圖寫在LINQ以下PLSQL查詢,但我來了一個小脫膠該組由:LINQ的加入和組由

select 
sub.EmpID, 
Min(sub.Stage1) Stage1, 
Min(sub.Stage2) Stage2, 
Min(sub.Stage3) Stage3, 
Min(sub.Prob1) Prob1, 
Min(sub.Prob2) Prob2 


from 

(select 
det.det_numbera EmpID, 
case when apr.apr_performa = '1' 
    then max(apr.apr_datec) 
    else null 
end Stage1, 
case when apr.apr_performa = '2' 
    then max(apr.apr_datec) 
    else null 
end Stage2, 
case when apr.apr_performa = '3' 
    then max(apr.apr_datec) 
    else null 
end Stage3, 
case when apr.apr_performa = '5' 
    then max(apr.apr_datec) 
    else null 
end Prob1, 
case when apr.apr_performa = '6' 
    then max(apr.apr_datec) 
    else null 
end Prob2 

from emdet det 

left outer join emapr apr 
on det.det_numbera = apr.det_numbera 

group by det.det_numbera, apr.apr_performa) sub 

group by sub.Empid 

我已成功地部分做子查詢,但遭遇了挫折在分組之前,我可以得到外部查詢工作:

 public List<ComplianceDetails> MyComplianceDetails(List<JobDetail> staff, List<Compliance> compliance) 
    { 
     List<ComplianceDetails> compdet = 
      (from s in staff 
      join c in compliance on s.EmpID equals c.EmpId into staffcomp 
      from sc in staffcomp.DefaultIfEmpty() 
      group s by new { s.EmpID, sc.Stage } into grp 


      select new ComplianceDetails(
       s.EmpID, 
       s.Position, 
       s.Department, 
       s.Division, 
       s.Contract, 
       s.ContService, 
       s.Probation, 
       s.Sessional, 
       s.Teaching, 
       sc.Stage == "1" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null, 
       sc.Stage == "2" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null, 
       sc.Stage == "3" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null, 
       sc.Stage == "5" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null, 
       sc.Stage == "6" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null 
       ) 
      ).ToList(); 
     return compdet; 
    } 

編輯//

感謝您的幫助,您指引我非常接近這個似乎工作的解決方案,預期:

 public List<ComplianceDetails> MyComplianceDetails(List<JobDetail> staff, List<Compliance> compliance) 
    { 
     string[] tQuals = new string[] { "21", "22", "23", "24" }; 

     var compdet = 
      (from det in staff 
     join apr in compliance on det.EmpID equals apr.EmpId 
      into JoinedList 
     from apr in JoinedList.DefaultIfEmpty() 

     group new { det, apr } by 
       new 
       { 
        det.EmpID, 
        Stage = apr == null ? "" : apr.Stage 

       } into GroupedList 

     select GroupedList.Select(u => new 
      { 
        EmpID = u.det.EmpID, 
        FullName = u.det.FullName, 
        Position = u.det.Position, 
        Department = u.det.Department, 
        Division = u.det.Division, 
        Contract = u.det.Contract, 
        ContService = u.det.ContService, 
        Probation = u.det.Probation, 
        Sessional = u.det.Sessional, 
        Teaching = u.det.Teaching, 
        Stage1 = u.apr == null ? null : (u.apr.Stage == "1" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null), 
        Stage2 = u.apr == null ? null : (u.apr.Stage == "2" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null), 
        Stage3 = u.apr == null ? null : (u.apr.Stage == "3" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null), 
        Prob1 = u.apr == null ? null : (u.apr.Stage == "5" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null), 
        Prob2 = u.apr == null ? null : (u.apr.Stage == "6" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null), 
        EduType = u.apr == null ? string.Empty : (tQuals.Contains(u.apr.Stage) ? u.apr.StageDesc : string.Empty), 
        EduDate = u.apr == null ? null : (tQuals.Contains(u.apr.Stage) ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null) 
       }) 
      ) 
      .SelectMany(u => u) 
      .GroupBy(u => u.EmpID) 
      .Select(u => new ComplianceDetails 
      (
       u.Key, 
       u.First().FullName, 
       u.First().Position, 
       u.First().Department, 
       u.First().Division, 
       u.First().Contract, 
       u.First().ContService, 
       u.First().Probation, 
       u.First().Sessional, 
       u.First().Teaching, 
       u.Where(t => t.Stage1 == u.Max(T => T.Stage1)).Select(g => g.Stage1).FirstOrDefault(), 
       u.Where(t => t.Stage2 == u.Max(T => T.Stage2)).Select(g => g.Stage2).FirstOrDefault(), 
       u.Where(t => t.Stage3 == u.Max(T => T.Stage3)).Select(g => g.Stage3).FirstOrDefault(), 
       u.Where(t => t.Prob1 == u.Max(T => T.Prob1)).Select(g => g.Prob1).FirstOrDefault(), 
       u.Where(t => t.Prob2 == u.Max(T => T.Prob2)).Select(g => g.Prob2).FirstOrDefault(), 
       u.Where(t => t.EduDate == u.Max(T => T.EduDate)).Select(g => g.EduType).FirstOrDefault(), 
       u.Where(t => t.EduDate == u.Max(T => T.EduDate)).Select(g => g.EduDate).FirstOrDefault() 
      )) 
      .ToList(); 

     return compdet; 
    } 

回答

1

這是你tsql相當於linq,檢查:

var query = (from det in emdet 
      join apr in emapr on det.det_numbera equals apr.det_numbera 
       into JoinedList 
      from apr in JoinedList.DefaultIfEmpty() 

      group new { det, apr } by 
        new 
        { 
         det.det_numbera, 
         apr_performa = apr == null ? "" : apr.apr.apr_performa 

        } into GroupedList 

      select GroupedList.Select(u => new 
       { 
        EmpID = u.det.det_numbera, 
        Stage1 = u.apr == null ? null : (u.apr.apr_performa == "1" ? GroupedList.Max(t => t.apr_datec) : null), 
        Stage2 = u.apr == null ? null : (u.apr.apr_performa == "2" ? GroupedList.Max(t => t.apr_datec) : null), 
        Stage3 = u.apr == null ? null : (u.apr.apr_performa == "3" ? GroupedList.Max(t => t.apr_datec) : null), 
        Prob1 = u.apr == null ? null : (u.apr.apr_performa == "5" ? GroupedList.Max(t => t.apr_datec) : null), 
        Prob2 = u.apr == null ? null : (u.apr.apr_performa == "6" ? GroupedList.Max(t => t.apr_datec) : null) 
       }) 
      ) 
      .SelectMany(u => u) 
      .GroupBy(u => u.EmpID) 
      .Select(u => new 
      { 
       EmpID = u.Key, 
       Stage1 = u.Where(t => t.Stage1 != null).DefaultIfEmpty().Min(t => t.Stage1), 
       Stage2 = u.Where(t => t.Stage2 != null).DefaultIfEmpty().Min(t => t.Stage2), 
       Stage3 = u.Where(t => t.Stage3 != null).DefaultIfEmpty().Min(t => t.Stage3), 
       Prob1 = u.Where(t => t.Prob1 != null).DefaultIfEmpty().Min(t => t.Prob1), 
       Prob2 = u.Where(t => t.Prob2 != null).DefaultIfEmpty().Min(t => t.Prob2) 
      }) 
      .ToList(); 
+0

嗨,感謝您的快速反應。我嘗試了一下你的例子,但是我在new {det.det_numbera,apr.apr_performa}這一行發現錯誤「Object reference not set to an object of a object」。我可以看到,det_numbera或「EmpId」有一個值,但有可能員工沒有階段,因此我認爲階段將是空的。 – mcinnes01

+0

我編輯了第一個'GroupBy',再次檢查,讓我知道是否有任何問題。 –

+0

嗨,感謝您的幫助,現在我似乎有點進一步了,它會到達第二個選擇,但在t.Stage1上從行中獲取另一個「未設置爲對象實例的對象引用」:Stage1 = u.Where (t => t.Stage1!= null).DefaultIfEmpty()。Min(t => t.Stage1),看起來好像t是空的?和想法?歡呼安迪 – mcinnes01