2011-04-16 54 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(); 
    }