需要帮助Linq Queries左外加入

时间:2011-04-16 15:13:53

标签: sql linq linq-to-sql group-by outer-join

我怎么能在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

需要帮助撰写Left Outer Join&在LINQ分组。

案例II:

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 个答案:

答案 0 :(得分: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);
              }

请注意,t.TestId子句中不需要q.TestIdgroup by,因为它们具有相同的值。对于最后一部分,我使用AsEnumerable,以便最终投影在内存中而不是在DB中执行,这样就可以使用string.Format

答案 1 :(得分: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)
    };

编辑:在阅读了Thomas Levesque的回答后,我意识到这不起作用,但以下应该是:

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();
    }