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

EF Core 7中如何在导航属性中使用非跟踪实体?

问题:EF Core 7中导航属性使用非跟踪实体导致SqlException的解决办法

我有一个基于Entity Framework Core 7开发的数据库处理类库,负责将实体返回给客户端代码,客户端会将这些实体赋值给导航属性,示例代码如下:

var newEntity = new SomeEntity {
  SomeProperty = "blah blah blah",
  SomeNavProperty = theLibrary.GetEntity()
};

theLibrary.Process(newEntity);  // 调用DbSet<TEntity>.Add
theLibrary.Save();  // 调用DbContext.SaveChanges

原本运行正常,但GetEntity方法返回的是跟踪实体,一旦客户端修改该实体的属性,调用SaveChanges时这些修改会被持久化到数据库,这不符合预期。于是我修改GetEntity让它返回非跟踪实体:

public SomeAnotherEntity GetEntity() {
  return dbContext.SomeAnotherEntities.AsNoTracking().SingleOrDefault(e => e.Id == 1);
}

这一修改导致DbContext的SaveChanges方法抛出SqlException,错误信息如下:

Cannot insert explicit value for identity column in table 'SomeAnotherEntities' when IDENTITY_INSERT is set to OFF.

请问如何在导航属性中使用来自AsNoTracking的非跟踪实体?或者说,怎么修复这个异常?注:在调用DbSet<TEntity>.Add前附加非跟踪关联实体的方法无效。


类库代码

实际的数据库操作类是泛型类,TEntity为处理的实体类型,Process方法代码如下:

public void Process(TEntity entity)
{
  int? id = (int?)typeof(TEntity).GetProperty("Id")?.GetValue(entity);
  if (id == null)
  {
    throw new InvalidOperationException("No Id property");
  }
            
  if (id == 0) table.Add(entity);
  else
  {
    var tracked = table.Find(id);
    if (tracked == null) return;
                
    foreach (var property in tracked.GetType().GetProperties())
    {
      if (property.Name == "Id") continue;
      property.SetValue(tracked, property.GetValue(entity));
    }
  }
}

table是存储TEntity类型实体的DbSet<TEntity>(已在构造函数中初始化)。Save方法仅调用SaveChanges。

参考用的SomeEntity实体定义:

public class SomeEntity {
  public int Id { get; set; }
  public string SomeProperty { get; set; }
  public SomeAnotherEntity SomeNavProperty { get; set; }
}

已尝试方案

我查找过类似问题,有两个相关提问:

  • 其中一个有答案,但对当前场景无效。
  • 另一个无有效答案,评论区也未提供解决方案,且在提问者补充完整代码前无法进一步解答。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:53:16