Efcore: [QUESTION] Left Join on 1..N required

Created on 17 Mar 2020  路  2Comments  路  Source: dotnet/efcore

I would like to understand why EF Core does a LEFT JOIN instead of INNER JOIN in the case where I have and 1..N relationship for this query.

using (var ctx = new MeuCtx(builder.Options))
{
    var query = ctx.Infos
        .Include(x => x.MoreInfo)
        .ToArray();
}

That is the SQL generated

SELECT [i].[Id], [i].[Name], [m].[Id], [m].[InfoId], [m].[InitialDate], [m].[LastDate]
FROM [Infos] AS [i]
LEFT JOIN [MoreInfo] AS [m] ON [i].[Id] = [m].[InfoId]
ORDER BY [i].[Id], [m].[Id]

Below you can see my Context and Models

public class MeuCtx : DbContext
{
    public MeuCtx(DbContextOptions<MeuCtx> options)
        : base(options)
    {

    }

    public DbSet<Info> Infos { get; set; }
    public DbSet<MoreInfo> MoreInfo { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var entityTypeBuilder = modelBuilder.Entity<Info>();

        entityTypeBuilder.HasKey(x => x.Id);

        entityTypeBuilder
            .HasMany(x => x.MoreInfo)
            .WithOne(x => x.Info)
            .IsRequired(true)
            .HasForeignKey(x => x.InfoId)
            .OnDelete(DeleteBehavior.Cascade);
    }
}

public class Info
{
    public long Id { get; set; }
    public string Name { get; set; }
    public List<MoreInfo> MoreInfo { get; set; }
}

public class MoreInfo
{
    public long Id { get; set; }
    public DateTime InitialDate { get; set; }
    public DateTime LastDate { get; set; }
    public long InfoId { get; set; }
    public Info Info { get; set; }
}
closed-question customer-reported

Most helpful comment

@AlbertoMonteiro you can still have Info entity without any MoreInfos. If we used inner join then the original entities would have been filtered out.

Required here means only that there cant be a MoreInfo without the Info. So the only time INNER JOIN is safe is for something like this:

    var query = ctx.MoreInfos
        .Include(x => x.Info)
        .ToArray();

All 2 comments

@AlbertoMonteiro you can still have Info entity without any MoreInfos. If we used inner join then the original entities would have been filtered out.

Required here means only that there cant be a MoreInfo without the Info. So the only time INNER JOIN is safe is for something like this:

    var query = ctx.MoreInfos
        .Include(x => x.Info)
        .ToArray();

Thank you very much.

Was this page helpful?
0 / 5 - 0 ratings