Pratik
Pratik

Reputation: 11745

Need help in Linq Queries left Outer Join

how can i write this in 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

Need help in writing Left Outer Join & Group by in LINQ .

Case 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 


Thanks.

Upvotes: 1

Views: 519

Answers (2)

svick
svick

Reputation: 244767

If you have the mappings, it should be easy without any joins:

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

EDIT: After reading Thomas Levesque's answer, I realized this wouldn't work, but the following should:

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

Upvotes: 0

Thomas Levesque
Thomas Levesque

Reputation: 292405

To perform an outer join in Linq, you need to use the DefaultIfEmpty extension method:

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

Note that you don't need both t.TestId and q.TestId in the group by clause, since they will have the same value. For the last part, I'm using AsEnumerable so that the final projection is performed in memory rather than in the DB, which enables the use of string.Format.

Upvotes: 2

Related Questions