SALE! All courses are on the lowest price! Enroll Now
Entity Framework

The New LeftJoin and RightJoin Methods in EF Core: Simplifying Joins in .NET 10

Bhrugen Patel

Bhrugen Patel

Author

Published
November 15, 2025
12 min read
138 views
Discover how the new LeftJoin and RightJoin methods in Entity Framework Core for .NET 10 simplify outer joins, making your LINQ queries more readable and maintainable than ever before.
Entity Framework Core - The Complete Guide

Entity Framework Core - The Complete Guide

Learn the basic's of Entity Framework in ASP.NET Core / .NET 7 as we start from scratch and learn advance concepts.

74 Videos 5hr 26min
Share this article:

LeftJoin and RightJoin in .NET 10: The Feature We've Been Waiting For

Okay, let's be real. If you've ever tried to do a left join in Entity Framework Core, you know the pain. That whole GroupJoinSelectManyDefaultIfEmpty dance? Yeah, nobody's writing that from memory without checking Stack Overflow first.

Well, good news! .NET 10 finally gave us what we've been asking for: actual LeftJoin and RightJoin methods. Let me show you why this is such a big deal.

The Old Way Was... Not Great

Remember this nightmare?

var result = await context.Students
    .GroupJoin(
        context.Departments,
        student => student.DepartmentID,
        department => department.ID,
        (student, departments) => new { student, departments })
    .SelectMany(
        x => x.departments.DefaultIfEmpty(),
        (x, department) => new
        {
            Name = x.student.FirstName,
            Dept = department.Name ?? "No Department"
        })
    .ToListAsync();

Like... what even is that? Every time I had to write this, I'd just copy-paste from a previous project and hope for the best.

The New Way Is Beautiful

Here's the same thing with the new LeftJoin:

var result = await context.Students
    .LeftJoin(
        context.Departments,
        student => student.DepartmentID,
        department => department.ID,
        (student, department) => new
        {
            Name = student.FirstName,
            Dept = department.Name ?? "No Department"
        })
    .ToListAsync();

That's it. That's the whole thing. It actually reads like English!

A Real Example: Blog Posts and Authors

Let's use something we can all relate to. Imagine you're building a blog (meta, I know).

public class BlogPost
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int? AuthorId { get; set; }
}

public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Sample Data:

BlogPosts Table:

Id Title AuthorId
1 Getting Started with .NET 101
2 Advanced C# Tips 102
3 Draft Post Ideas null
4 EF Core Performance 101

Authors Table:

Id Name
101 John Smith
102 Sarah Johnson
103 Mike Davis

Now you want to list ALL posts, even if some don't have an author assigned yet (maybe they're drafts or the author left the company).

With LeftJoin:

var posts = await context.BlogPosts
    .LeftJoin(
        context.Authors,
        post => post.AuthorId,
        author => author.Id,
        (post, author) => new
        {
            post.Title,
            AuthorName = author.Name ?? "Anonymous"
        })
    .ToListAsync();

LeftJoin Result (All Posts):

Title AuthorName
Getting Started with .NET John Smith
Advanced C# Tips Sarah Johnson
Draft Post Ideas Anonymous ← No author? No problem!
EF Core Performance John Smith

✅ What Happened?

LeftJoin kept ALL posts (left table) and matched them with authors where possible. The "Draft Post Ideas" didn't have an author, so we used "Anonymous" as the default value.

What About RightJoin?

RightJoin is like LeftJoin's mirror twin. It keeps everything from the RIGHT table instead.

var authorsAndPosts = await context.Authors
    .RightJoin(
        context.BlogPosts,
        author => author.Id,
        post => post.AuthorId,
        (author, post) => new
        {
            PostTitle = post.Title,
            AuthorName = author.Name ?? "No Author"
        })
    .ToListAsync();

RightJoin Result (All Posts, Matched with Authors):

PostTitle AuthorName
Getting Started with .NET John Smith
Advanced C# Tips Sarah Johnson
Draft Post Ideas No Author
EF Core Performance John Smith

📝 Notice

Notice that Mike Davis (author 103) doesn't appear in the results because he has no blog posts. RightJoin kept all POSTS (right table) and matched authors where they exist.

But Wait, What About Navigation Properties?

Fair question! If you've set up your entities properly with navigation properties, you can often do this:

var posts = await context.BlogPosts
    .Include(p => p.Author)
    .Select(p => new
    {
        p.Title,
        AuthorName = p.Author.Name ?? "Anonymous"
    })
    .ToListAsync();

So When Do I Use LeftJoin?

Good rule of thumb:

Use navigation properties when:

  • You have a proper relationship defined in your models
  • You're working with your main domain entities
  • You need to update or delete things

Use LeftJoin when:

  • You're doing reporting or analytics
  • You need to join tables that don't have a relationship
  • You're writing read-only queries
  • You want more control over the exact SQL being generated

💡 Think of it like this: navigation properties are for your app's main workflows, LeftJoin is for when you need to do something special.

The Bottom Line

These new methods are one of those "finally!" moments. They make code easier to write, easier to read, and easier to maintain. No more copying mysterious GroupJoin code from Stack Overflow.

⚡ Quick Reference:

  • LeftJoin keeps everything from the left (first) table
  • RightJoin keeps everything from the right (second) table
  • Use ?? to handle nulls when there's no match
  • Remember: Both tables participate, but one table's records are always included

That's really all there is to it. Happy coding!

Watch Video Tutorial

Bhrugen Patel

About Bhrugen Patel

Expert .NET developer and educator with years of experience in building real-world applications and teaching developers around the world.

FREE .NET Hosting
YouTube
Subscribe