参考:https://blog.csdn.net/qq_18638761/article/details/107833999
https://www.cnblogs.com/stgp/p/12294454.html
发生的原因,在CheckProductionCode()方法中根据主键id查询对象时没有使用AsNoTracking(),示例:_db.Productions.AsNoTracking()
那么EF会把查询出的对象缓存并跟踪对象状态,之后再Update的时候就会查询现有已跟踪的对象,发现已经存在一个相同主键的对象,所以报错。
https://www.cnblogs.com/stgp/p/12294454.html
发生的原因,在CheckProductionCode()方法中根据主键id查询对象时没有使用AsNoTracking(),示例:_db.Productions.AsNoTracking()
那么EF会把查询出的对象缓存并跟踪对象状态,之后再Update的时候就会查询现有已跟踪的对象,发现已经存在一个相同主键的对象,所以报错。
/// <summary> /// 编辑修改商品 /// </summary> /// <param name="dto"></param> /// <exception cref="Exception"></exception> public void EditProduction(Production dto) { bool res = CheckProductionCode(dto); if (!res) { throw new Exception("商品编码重复"); } _db.Productions.Update(dto); _db.SaveChanges(); }
CheckProductionCode
public bool CheckProductionCode(Production dto) { var res = _db.Productions.Where(x => x.ProductionId == dto.ProductionId).FirstOrDefault(); //.... return true; }
解决办法1:查询的时候禁用状态跟踪 _db.Productions.AsNoTracking()
解决办法2:在Program.cs中配置数据库的时候,设置所有查询禁用跟踪
// 使用 Pomelo.EntityFrameworkCore.MySql builder.Services.AddDbContext<DataMgrContext>(opt => { string connStr = builder.Configuration.GetConnectionString("MysqlContext") + ""; var serverVersion = ServerVersion.AutoDetect(connStr); opt.UseMySql(connStr, serverVersion); //重要,不跟踪查询得到的实体。 opt.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); });
注意,一旦设置了AsNoTracking() 或 opt.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); 后,查询出来的对象,修改属性,然后_db.SaveChanges();这样的方法就不能修改成功了。
需要使用 _db.Productions.Update(dto); _db.SaveChanges();这样的方式才行。
/// <summary> /// 编辑修改商品 /// </summary> /// <param name="dto"></param> /// <exception cref="Exception"></exception> public void EditProduction(Production dto) { bool res = CheckProductionCode(dto); if (!res) { throw new Exception("商品编码重复"); } _db.Productions.Update(dto); _db.SaveChanges(); //设置了AsNoTracking() 或 opt.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);后这样的方法就不能修改成功了。 //var eto = _db.Productions.Where(x => x.ProductionId == dto.ProductionId).FirstOrDefault(); //eto.ProductionName = dto.ProductionName; //_db.SaveChanges(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
2023-10-16 Mysql之IF THEN ELSEIF THEN ELSE、CASE WHEN THEN