2011-04-16 50 views
1

我怎麼可以這樣寫在LINQ:在LINQ查詢需要幫助的左外連接

SELECT 
    T.TestId, 
    S.SubjectName+' >> '+T.TestName +' ('+ CONVERT(VARCHAR(10),COUNT(Q.TestId)) +')' TestData 
FROM 
    Test T LEFT OUTER JOIN Subject S 
    ON T.SubjectId = S.SubjectId 
    LEFT OUTER JOIN Quest Q 
    ON T.TestId = Q.TestId 
GROUP BY 
    Q.TestId, 
    T.TestId, 
    T.TestName, 
    S.SubjectName 
ORDER BY 
    COUNT(Q.TestId) DESC 

書面左外的LINQ加入&集團通過需要幫助。

案例二:

SELECT 
    S.SubjectName, 
    T.TestName, 
    Q.Question, 
    A.Answer, 
    A.IsCorrect 
FROM Ans A 
    INNER JOIN Quest Q 
    ON A.QuestId = Q.QuestId 
    AND A.QuestId IN (SELECT 
          Q.QuestId 
         FROM Quest Q 
          INNER JOIN Test T 
          ON Q.TestId = T.TestId) 
    INNER JOIN Subject S 
    ON A.SubjectId = S.SubjectId 
    INNER JOIN Test T 
    ON A.TestId = T.TestId 


感謝。

回答

2

要執行的LINQ外連接,你需要使用DefaultIfEmpty擴展方法:

var query = 
    from t in db.Test 
    join s in db.Subject on t.SubjectId equals s.SubjectId into testSubject 
    from s in testSubject.DefaultIfEmpty() 
    join q in db.Quest on t.TestId equals q.TestId into testQuest 
    from q in testQuest.DefaultIfEmpty() 
    group by new 
    { 
     t.TestId, 
     t.TestName, 
     s.SubjectName 
    } 
    select new 
    { 
     g.Key.TestId, 
     g.Key.TestName, 
     g.Key.SubjectName, 
     Count = g.Count() 
    }; 

var results = from r in query.AsEnumerable() 
       select new 
       { 
        r.TestId, 
        TestData = string.Format("{0} >> {1} ({2})", r.SubjectName, t.TestName, r.Count); 
       } 

請注意,您不需要group by子句中都t.TestIdq.TestId,因爲它們具有相同的值。對於最後一部分,我使用AsEnumerable,以便在內存中執行最終投影,而不是在DB中執行,這使得可以使用string.Format

0

如果你有映射,它應該很容易,沒有任何連接:

from test in tests 
let count = test.Quests.Count() 
orderby count descending 
select 
    new 
    { 
     test.Id, 
     TestData = 
      test.Subject == null 
       ? null 
       : string.Format("{0} >> {1} ({2})", test.Subject.Name, test.Name, count) 
    }; 

編輯:閱讀托馬斯·萊維斯克的回答後,我意識到這是行不通的,但應該如下:

var query = from test in tests 
      let count = test.Quests.Count() 
      orderby count descending 
      select 
       new 
       { 
        test.Id, 
        test.Name, 
        test.Subject, 
        Count = count 
       }; 

var results = query 
    .AsEnumerable() 
    .Select(
     t => 
     new 
     { 
      t.Id, 
      TestData = 
      t.Subject == null 
       ? null 
       : string.Format("{0} >> {1} ({2})", t.Subject.Name, t.Name, t.Count) 
     }); 

     results.Dump(); 
    }