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

EF Core 6关联SAP现有数据库Include查询结果不符问题排查

问题描述

在EF Core 6中映射SAP现有数据库的无关联表,已配置多对多与一对一实体关系,代码如下:

// 多对多关系配置
modelBuilder.Entity<Actividad>().ToTable("OCLG");
modelBuilder.Entity<Proyecto>().ToTable("OPRJ");
modelBuilder.Entity<Empleado>().ToTable("OHEM");
modelBuilder.Entity<Usuario>().ToTable("OUSR");
modelBuilder.Entity<Fase>().ToTable("[@ITAPROYSEG]");

modelBuilder.Entity<Actividad>()
    .HasKey(a => new { a.U_Proy, a.U_Fase, a.AttendUser});

modelBuilder.Entity<Actividad>()
    .HasOne(a => a.Proyecto)
    .WithMany(p => p.Actividades)
    .HasForeignKey(a => a.U_Proy);

modelBuilder.Entity<Actividad>()
    .HasOne(a => a.Fase)
    .WithMany(f => f.Actividades)
    .HasForeignKey(a => a.U_Fase);

modelBuilder.Entity<Actividad>()
    .HasOne(a => a.Usuario)
    .WithMany(u => u.Actividades)
    .HasForeignKey(a => a.AttendUser);
// 一对一实体类
public class Empleado
{       
    public int EmpId { get; set; }
    
    [Key]
    public string U_CodEmpl { get; set; }

    public string Email { get; set; }

    public string FirstName { get; set; }

    public string MiddleName { get; set; }

    public string LastName { get; set; }

    public string NombreCompleto=>$"{FirstName} {MiddleName} {LastName}";

    public Usuario Usuario { get; set; }
}

public class Usuario
{
    [Key]
    [Column(TypeName ="smallint")]
    public int Internal_K { get; set; }

    [ForeignKey("Empleado")]
    public string User_Code { get; set; }

    public Empleado Empleado { get; set; }

    public List<Actividad> Actividades { get; set; }

}

直接在数据库查询目标数据可得到479行,但使用以下EF Core查询仅能得到143条Actividades数据,原生SQL查询则能得到正确结果:

var empleado = _context.Empleados.Include(e => e.Usuario).ThenInclude(u => u.Actividades).FirstOrDefault(e => e.U_CodEmpl == codigoSAPEmpleado);
原因分析
  1. Actividad与Usuario的关联字段匹配错误:
    当前配置中,Actividad的AttendUser外键被默认关联到Usuario的主键Internal_K,但两者类型不匹配(AttendUser为字符串,Internal_K为整数),且数据库中AttendUser实际应关联Usuario的User_Code字段。EF Core基于错误的关联条件生成SQL,导致大量符合条件的Actividad被过滤。
  2. 一对一关系配置不明确:
    Empleado与Usuario的一对一关系仅通过属性标注了外键,但未在DbContext中显式定义关联规则,EF Core可能采用默认的主键关联逻辑,导致查询时的连接逻辑与数据库实际关联规则不符。
解决方法

1. 修正Actividad与Usuario的关联关系

修改Actividad的关系配置,明确指定关联Usuario的User_Code字段:

modelBuilder.Entity<Actividad>()
    .HasOne(a => a.Usuario)
    .WithMany(u => u.Actividades)
    .HasForeignKey(a => a.AttendUser)
    .HasPrincipalKey(u => u.User_Code); // 指定关联Usuario的User_Code字段而非主键

2. 完善Empleado与Usuario的一对一关系配置

在DbContext的OnModelCreating方法中显式配置一对一关系,明确双方的关联字段:

modelBuilder.Entity<Empleado>()
    .HasOne(e => e.Usuario)
    .WithOne(u => u.Empleado)
    .HasForeignKey<Usuario>(u => u.User_Code)
    .HasPrincipalKey<Empleado>(e => e.U_CodEmpl);

3. 验证生成的SQL(可选)

通过EF Core日志功能查看生成的SQL语句,确认关联条件与原生SQL一致:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:20:37