Entity Framework 6 - Outer Joins and Method Syntax Queries

458 views Asked by At

I'm trying to re-write the following SQL LEFT OUTER JOIN query using Entity Framework 6:

select tblA.*, tblB.*
from dbo.TableA tblA left outer join dbo.TableB tblB on 
    tblA.Student_id=tblB.StudentId and tblA.other_id=tblB.OtherId
where tblB.Id is null

Here's my current C# code:

using (var db = EFClass.CreateNewInstance())
{
    var results = db.TableA.GroupJoin(
        db.TableB,
        tblA => new { StudentId = tblA.Student_id, OtherId = tblA.other_id },
        tblB => new { tblB.StudentId, tblB.OtherId },
        (tblA, tblB) => new { TableAData = tblA, TableBData = tblB }
    )
    .Where(x => x.TableBData.Id == null)
    .AsNoTracking()
    .ToList();

    return results;
}

And here's the following compiler error I'm getting:

The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.

In a nutshell: I need to OUTER JOIN the two DbSet objects made available via Entity Framework, using more than one column in the join.

I'm also fairly certain this won't do a LEFT OUTER JOIN properly, even if I wasn't getting a compiler error; I suspect I need to involve the DefaultIfEmpty() method somehow, somewhere. Bonus points if you can help me out with that, too.

UPDATE #1: It works if I use a strong type in the join... is it simply unable to handle anonymous types, or am I doing something wrong?

public class StudentOther
{
    public int StudentId { get; set; }
    public int OtherId { get; set; }
}

using (var db = EFClass.CreateNewInstance())
{
    var results = db.TableA.GroupJoin(
        db.TableB,
        tblA => new StudentOther { StudentId = tblA.Student_id, OtherId = tblA.other_id },
        tblB => new StudentOther { StudentId = tblB.StudentId, OtherId = tblB.OtherId },
        (tblA, tblB) => new { TableAData = tblA, TableBData = tblB }
    )
    .Where(x => x.TableBData.Id == null)
    .AsNoTracking()
    .ToList();

    return results;
}
1

There are 1 answers

1
Arasu RRK On

can you please try this solution? I'm not sure about the result :(

(from tblA in dbo.TableA
join tblB in dbo.TableB on new { tblA.Student_id, tblA.other_id } equals new { blB.StudentId, tblB.OtherId }
into tblBJoined
from tblBResult in tblBJoined.DefaultIfEmpty()
where tblBResult.Id == null
select new {
    TableAData = tblA,
    TableBData = tblB
}).ToList();