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

EF Core 5+可选多对多AsSplitQuery生成INNER JOIN丢失数据问题

运行环境
  • .NET 5
  • EF Core 5
  • SQL Server
问题描述

需要通过Include().ThenInclude()语法对可选多对多关系生成LEFT JOIN查询,但EF Core实际生成INNER JOIN,导致不存在关联关系的记录被过滤丢失。

当前业务涉及三张表:A、B、AB,其中AB为A和B的多对多关联表;由于AB表需存储额外字段,未采用EF Core隐式多对多映射实现。

涉及表结构

表A

ID
1
2
...

表B

ID
1
2
...

关联表AB

IDAIDBID
111
212
.........

C#实体模型定义

public class A
{
  public Guid ID { get; set; }
  public ICollection<AB> ABs { get; set; }
}
public class B
{
  public Guid ID { get; set; }
  public ICollection<AB> ABs { get; set; }
}
public class AB
{
  public Guid ID { get; set; }
  public Guid AID { get; set; }
  public Guid BID { get; set; }
  public A A { get; set; }
  public B B { get; set; }
}

初始查询实现

context.As
       .AsSplitQuery()
       .Include(f => f.ABs)
           .ThenInclude(f => f.B)
       .ToList();

当A记录存在对应AB关联数据时,查询逻辑正常,可正常获取A关联的所有B记录;但当A记录在AB表中无对应关联行(即未分配任何B关联数据)时,EF Core生成的SQL使用INNER JOIN关联,直接过滤掉了所有无对应AB记录的A行。

已尝试的排查方案

  • 为导航属性添加可空标记:EF Core 5取消了显式标记关系为必填/可选的配置方式,改为通过模型中导航属性是否可为空自动推断关系类型。但ICollection类型本身天然可为空,代码中指向的B实体类型也为引用类型可为空,即使主动为属性添加?可空标记(如public ICollection<AB>? ABs { get; set; }),生成的SQL仍未发生变化。
  • 通过Fluent API显式配置多对多关系:参考公开方案在DbContext中配置多对多关系,仍未改变该行为,配置代码如下:
modelBuilder.Entity<A>()
            .HasMany(f => f.Bs)
            .WithMany(f => f.As);

待解决疑问

除手动编写JOIN语句外,是否有方案可强制EF Core将AB导航属性识别为可选关系,生成正确的LEFT JOIN?


问题排查更新

经测试,该现象为使用AsSplitQuery()方法的副作用,将查询改为AsSingleQuery()模式后可正常生成LEFT JOIN。
目前推测该问题与拆分查询模式下ThenInclude()加载非空一对多关系的生成逻辑有关,待进一步确认两点:

  • 该现象是否为EF Core的已知bug
  • 是否存在配置方式可告知EF Core上游关系为可选,即使下游关系为必填也可在拆分查询模式下生成正确的LEFT JOIN逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:57:17