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

开启IDENTITY_INSERT后仍报错,修改非标识字段触发问题求助

解决IDENTITY_INSERT开启后仍报错的问题

你的问题其实出在删除实体后重新添加时,EF仍然会尝试插入原有标识列的值,哪怕你只修改了非标识字段OrderValue。让我拆解下原因和解决方案:

问题根源

当你用db.games.Remove(gg)删除实体后,这个实体对象的id属性依然保留着原来的数值。当你调用db.games.Add(gg)时,EF会把这个对象当作全新的实体,尝试插入所有字段(包括id)。而你的game表中id是标识列,默认由数据库自动生成,所以数据库会拒绝手动插入id值——哪怕你开启了IDENTITY_INSERT,也可能因为上下文跟踪的状态不对导致报错。

而且更关键的是:你的需求只是修改OrderValue,完全没必要走“删除再添加”的流程,这是绕远路还触发了不必要的问题。

最优解决方案:直接修改字段保存

既然你的目标只是更新OrderValue,直接找到实体修改后保存即可,这是EF的常规用法:

public ActionResult Position(int ID) 
{
    var gg = db.games.Find(ID);
    gg.OrderValue = 42; // 直接修改目标字段
    db.SaveChanges();   // 保存修改,EF会自动生成UPDATE语句
    return RedirectToAction("Admin");
}

如果必须删除再添加(业务需求)

如果因为某些业务逻辑,你一定要删除实体后重新添加,那需要处理标识列的问题:

方案1:重置标识列值,让数据库重新生成

把实体的id设为默认值(SQL Server中int类型标识列设为0,数据库会自动生成新的标识值):

public ActionResult Position(int ID) 
{
    var gg = db.games.Find(ID);
    db.games.Remove(gg);
    db.SaveChanges(); // 先提交删除操作

    gg.id = 0; // 重置标识列,让DB生成新值
    gg.OrderValue = 42;
    db.games.Add(gg);
    db.SaveChanges();

    return RedirectToAction("Admin");
}

方案2:保留原有ID,正确开启IDENTITY_INSERT

如果你需要保留原来的id值,那必须确保IDENTITY_INSERT的开启和关闭包裹住整个插入操作,并且EF明确知道要插入标识列的值:

public ActionResult Position(int ID) 
{
    var gg = db.games.Find(ID);
    db.games.Remove(gg);
    db.SaveChanges(); // 先完成删除

    gg.OrderValue = 42;
    // 开启IDENTITY_INSERT
    db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT game ON");
    db.games.Add(gg);
    db.SaveChanges();
    // 操作完成后务必关闭,避免影响后续操作
    db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT game OFF");

    return RedirectToAction("Admin");
}

注意:IDENTITY_INSERT一次只能对一个表开启,操作完成后一定要关闭,否则其他针对该表的插入操作可能会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:44:35