You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core中Include()未生成LEFT JOIN问题排查及解决

EF Core Include生成INNER JOIN而非LEFT JOIN的排查解决

在开发中需要获取多个导航属性数据用于前端展示,使用.Include()进行关联查询。已知当导航属性可为空、数据库列允许为null时,EF Core应该生成LEFT JOIN,但实际查询仍使用INNER JOIN,尽管对应的外键列都是可空类型。

查询代码

var listOfProductsOnSets = await productWithSetsRepository
            .FindQueryable(asoc => asoc.IdSet == idSet)
            .Include(c => c.AsCuloare)
                .ThenInclude(cc => cc!.CodCuloare)
            .Include(d => d.AsDimensiune)
            .AsSplitQuery()
            .ToListAsync();

实体类定义

public class AsociereSeturi
{
    // Attributes
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int IdAsociereSet { get; init; }
    
    // Foreign Keys
    public int IdProdus { get; init; }
    public Produse Produs { get; init; } = null!;
    
    public int IdSet { get; init; }
    public Seturi Set { get; init; } = null!;
    
    public int? IdCuloare { get; init; }
    public Culori? AsCuloare { get; init; } 
    public int? IdDimensiune { get; init; }
    public Dimensiuni? AsDimensiune { get; init; } 
    
    public ICollection<ProduseCuComenzi> CombinatieSetPeComanda { get; } 
}

生成的SQL日志

SELECT a.id_asociere_set, a.id_culoare, a.id_dimensiune, a.id_produs, a.id_set, 
       c.id_culoare, c.id_cod_culoare, c.nume_culoare, 
       d.id_dimensiune, d.latime, d.lungime, d.PerdeaEstePereche, d.recomandare_pat
FROM asociere_seturi AS a
INNER JOIN culori AS c ON a.id_culoare = c.id_culoare
INNER JOIN dimensiuni AS d ON a.id_dimensiune = d.id_dimensiune
WHERE a.id_set = @__idSet_0;

排查结果

问题根源在于AsociereSeturi的OnModelCreating配置中,给IdDimensiune添加了.IsRequired()约束。即使实体类中IdDimensiune定义为可空的int?,这个配置会强制EF Core将该外键视为必填,从而生成INNER JOIN。移除.IsRequired()配置后,查询正常生成LEFT JOIN。

内容的提问来源于stack exchange,提问作者Misu Stefan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 00:44:56