2014-09-30 73 views
-2

我想將以下SQL查詢轉換爲LINQ表達式(使用Entity Framework 6.1)。到目前爲止,我一直無法找到一個可接受的LINQ表達式來產生類似的結果。任何幫助把這個簡單的SQL語句變成一個LINQ表達將不勝感激。LINQ JOIN和OUTER JOIN - 如何將SQL轉換爲LINQ表達式

SELECT AAG.Id AS GroupId, 
    A.Id AS ActivityId, 
    A.Title As Title, 
    CASE WHEN AA.CompletedOn IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS Completed, 
    COALESCE(AAG.PointValue, 0) + SUM(COALESCE(AQ.PointValue, 0)) AS PointTotal 
FROM ActivityAssignmentGroup AAG 
INNER JOIN ActivityAssignment AA ON AA.GroupId = AAG.Id 
INNER JOIN Activity A ON AA.ActivityId = A.Id 
LEFT OUTER JOIN ActivityQuestion AQ ON AQ.ActivityId = A.Id 
WHERE AAG.AssignedToId = 6 
GROUP BY AAG.Id, A.Id, A.Title, CASE WHEN AA.CompletedOn IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END, COALESCE(AAG.PointValue,0) 

沒有LEFT OUTER JOIN部分,下面的LINQ語句是部分完成,但我無法找出適當的語法來添加LEFT OUTER JOIN條件:

var assignments = await (from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId) 
           join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId 
           join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id 
           select new ActivityListViewModel 
           { 
            Id = a.Id, 
            Points = g.PointValue ?? 0, 
            Title = a.Title, 
            GroupId = g.Id, 
            Complete = (aa.CompletedOn != null) 
           }); 

編輯:

感謝您的迴應Bob。我試圖使用DefaultIfEmpty並查看由Entity Framework生成的結果SQL查詢,但它不起作用。在發表這篇文章之前,這是我嘗試的LINQ聲明:

var assignments = from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId) 
       join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId 
       join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id 
       from aq in db.ActivityQuestions.Where(q => q.ActivityId == a.Id).DefaultIfEmpty() 
       group aq by new { ActivityId = aq.ActivityId, Title = a.Title, GroupId = g.Id, Points = g.PointValue ?? 0, Completed = (aa.CompletedOn != null) } into s 
       select new ActivityListViewModel 
       { 
        Id = s.Key.ActivityId, 
        Points = s.Key.Points + s.Sum(y => y.PointValue ?? 0), //g.PointValue ?? 0, 
        Title = s.Key.Title, 
        GroupId = s.Key.GroupId, 
        Complete = s.Key.Completed 
       }; 

當然,它也沒有工作。結果是項目缺少Id(ActivityId)。

+0

所以你只需要添加外部連接到你的linq?聽起來很直截了當。不知道爲什麼downvotes。 – paqogomez 2014-09-30 21:40:46

+0

我也不確定倒票。如果我沒有花費大量時間來解決問題,我不會發布。即使嘗試Linqer無濟於事。 – Aggromonster 2014-10-01 15:14:05

+0

我想你應該使用'g.Id'而不是's.Key.ActvityID' – paqogomez 2014-10-01 15:21:01

回答

0

只是爲了關閉循環(謝謝你鮑勃淡水河谷)...下面的查詢工作:

var assignments = from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId) 
          join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId 
          join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id 
          from aq in db.ActivityQuestions.Where(q => q.ActivityId == a.Id).DefaultIfEmpty() 
          group aq by new { ActivityId = a.Id, Title = a.Title, GroupId = g.Id, Points = g.PointValue ?? 0, Completed = (aa.CompletedOn != null) } into s 
          select new ActivityListViewModel 
          { 
           Id = s.Key.ActivityId, 
           Points = s.Key.Points + s.Sum(y => y.PointValue ?? 0), //g.PointValue ?? 0, 
           Title = s.Key.Title, 
           GroupId = s.Key.GroupId, 
           Complete = s.Key.Completed 
          }; 

該問題是由條件和使用ag.ActivityId時,我應該使用a.Id.

1

你需要DefaultIfEmpty()轉換一個加盟左外連接,documentition從MSDN here

var assignments = await (from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId) 
          join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId 
          join a1 in db.Activities.AsNoTracking() on aa.ActivityId equals a1.Id into a2 
          from a in a2.DefaultIfEmpty() 
          select new ActivityListViewModel 
          { 
           Id = a == null ? null : a.Id, 
           Points = g.PointValue ?? 0, 
           Title = a == null ? null : a.Title, 
           GroupId = g.Id, 
           Complete = (aa.CompletedOn != null) 
          }); 
+0

Bob Vale - 感謝你的迴應。我的原始查詢有效,但不完整。我需要將一個連接添加到ActivityQuestion集合中。 我想要得到的是該活動的總積分。積分可以在組級別或活動級別應用(並且可能兩者,儘管實際上不太可能)。我添加了一個編輯來顯示每個問題的總和。 一個活動組可以有多個活動。活動可以(可選)有多個問題(0到1或更多)。最終結果應該是一系列活動及其可能的要點。 – Aggromonster 2014-10-01 15:19:19

+0

@Aggromonster看看paqogomez對你的問題的評論,你在羣裏使用了錯誤的ID ... – 2014-10-02 09:41:08

+0

再次感謝你。你是個學者和紳士。不能相信我以前沒有發現過。看起來我確實得到了正確的查詢,但在我的聯合分配上失敗。 – Aggromonster 2014-10-02 14:10:12