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

EF Core为何生成TempId列?关联查询报错问题咨询

EF Core 查询生成不存在的TempId列问题分析

问题场景

实体与关联配置

[Table("Common_T229")]
public class OrderDetail {
    [Column("F229_ID")]
    public int Id { get; set; }

    // ... 其他列

    public virtual ICollection<OrderDetailTimeRange> TimeRanges { get; set; } = new Collection<OrderDetailTimeRange>();
}

[Table("WP_OpPlanAuftragZeitrahmen")]
public class OrderDetailTimeRange {
    [Column("Id")]
    public int Id { get; set; }

    // ... 其他列

    public OrderDetail OrderDetail { get; set; }
}

public class E3kDbContext : DbContext {
    public DbSet<OrderDetail> OrderDetails { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder.Entity<OrderDetail>()
                    .HasMany(m => m.TimeRanges)
                    .WithOne(d => d.OrderDetail)
                    .HasForeignKey(d => d.OrderNumber)
                    .OnDelete(DeleteBehavior.Cascade);
    }
}

查询代码

public IEnumerable<OrderDetailDto> SearchData() {
    var e3k = ContextProviderService.GetE3kContext();

    IQueryable<OrderDetail> query = e3k.OrderDetails.Include(x => x.TimeRanges);
    query = query.Take(5000);

    foreach (var data in query) {
         // ... 处理逻辑
    }

    // ...
}

错误信息

fail: 05.06.2023 18:30:30.800 RelationalEventId.CommandError[20102] (Microsoft.EntityFrameworkCore.Database.Command)
  Failed executing DbCommand (41ms) [Parameters=[@__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
  SELECT [t].[F229_ID], [t].[F229_70], [t].[F229_34], [t].[F229_36], [t].[F229_03], [t].[F229_02], [t].[F229_89], [t].[TempId], [w].[Id], [w].[Von], [w].[Feiertag], [w].[AnzahlMitarbeiter], [w].[AuftragsNr], [w].[Samstag], [w].[Sonntag], [w].[Zeit], [w].[Bis]
  FROM (
      SELECT TOP(@__p_0) [c].[F229_ID], [c].[F229_70], [c].[F229_34], [c].[F229_36], [c].[F229_03], [c].[F229_02], [c].[F229_89], [c].[TempId]
      FROM [Common_T229] AS [c]
  ) AS [t]
  LEFT JOIN [WP_OpPlanAuftragZeitrahmen] AS [w] ON [t].[TempId] = [w].[AuftragsNr]
  ORDER BY [t].[F229_ID]
dbug: 05.06.2023 18:30:30.802 RelationalEventId.ConnectionClosing[20002] (Microsoft.EntityFrameworkCore.Database.Connection)
      Closing connection to database 'Dev_e3k_DietscheV6' on server '62.2.129.5\SQL2017,1433'.
dbug: 05.06.2023 18:30:30.805 RelationalEventId.ConnectionClosed[20003] (Microsoft.EntityFrameworkCore.Database.Connection)
      Closed connection to database 'Dev_e3k_DietscheV6' on server '62.2.129.5\SQL2017,1433' (2ms).
fail: 05.06.2023 18:30:30.820 CoreEventId.QueryIterationFailed[10100] (Microsoft.EntityFrameworkCore.Query)
      An exception occurred while iterating over the results of a query for context type 'Dik.WebApp.DataAccess.E3kDbContext'.
      Microsoft.Data.SqlClient.SqlException (0x80131904): Invalid column name 'TempId'.

问题

EF Core为何会生成不存在的TempId列?


原因分析

错误的核心是关联关系配置不完整,导致EF Core无法正确识别主表与子表的关联逻辑,进而生成了错误的SQL:

  1. 你在关联配置中指定子表外键为d => d.OrderNumber,但OrderDetailTimeRange实体中并未定义该属性,EF Core尝试自动生成影子属性,但后续关联逻辑出现偏差;
  2. 同时,你没有显式指定主表OrderDetail用于关联的属性(默认EF Core会使用主表主键,但你的外键实际关联的是主表的非主键列),EF Core无法定位正确的关联字段,最终错误生成了不存在的TempId列。

另外,EF Core执行Take+Include查询时,需要先对主表分页再关联子表,这一步高度依赖正确的关联键来保证数据准确性,缺失的配置会直接导致SQL生成逻辑出错。

解决方法

步骤1:补全子表外键属性

在OrderDetailTimeRange实体中添加外键属性,并映射到数据库实际列名:

[Table("WP_OpPlanAuftragZeitrahmen")]
public class OrderDetailTimeRange {
    [Column("Id")]
    public int Id { get; set; }

    // 添加外键属性,类型匹配数据库AuftragsNr列的实际类型
    [Column("AuftragsNr")]
    public int OrderNumber { get; set; }

    // ... 其他列

    public OrderDetail OrderDetail { get; set; }
}

步骤2:补全主表关联属性(若缺失)

如果OrderDetail实体中没有对应数据库关联列的属性,需要添加并映射:

[Table("Common_T229")]
public class OrderDetail {
    [Column("F229_ID")]
    public int Id { get; set; }

    // 添加主表关联列,类型匹配数据库对应列的实际类型
    [Column("AuftragsNr")]
    public int OrderNumber { get; set; }

    // ... 其他列

    public virtual ICollection<OrderDetailTimeRange> TimeRanges { get; set; } = new Collection<OrderDetailTimeRange>();
}

步骤3:完善关联配置

显式指定主表的关联属性与子表的外键属性,确保EF Core能正确识别关联逻辑:

protected override void OnModelCreating(ModelBuilder modelBuilder) {
    modelBuilder.Entity<OrderDetail>()
                .HasMany(m => m.TimeRanges)
                .WithOne(d => d.OrderDetail)
                .HasPrincipalKey(m => m.OrderNumber) // 指定主表用于关联的属性
                .HasForeignKey(d => d.OrderNumber)    // 指定子表的外键属性
                .OnDelete(DeleteBehavior.Cascade);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:13:12