Entity Framework下GenericDAO更新方法无异常但不生效的解决办法
嘿,我看了你的代码,马上就找到问题所在了——你的update方法里只把实体状态标记为了修改,但完全漏掉了提交更改到数据库的关键步骤!和insert、delete方法对比就能发现,这两个方法都调用了context.SaveChanges()来把内存中的变更同步到数据库,但update方法里没有这一行,所以修改根本没落地,而且因为没触发数据库操作,自然也不会抛出异常。
第一步:修复Update方法
直接在update方法里添加context.SaveChanges(),同时优化一下异常处理避免空引用:
public Boolean update(T obj) { try{ context.Entry<T>(obj).State = System.Data.Entity.EntityState.Modified; context.SaveChanges(); // 新增这行,提交变更到数据库 return true; }catch (Exception e){ // 优化异常信息:优先取内部异常,没有则用外层异常 Debug.WriteLine("Update error: " + (e.InnerException?.Message ?? e.Message)); return false; } }
额外优化建议
1. 简化更新逻辑(可选)
因为你是通过同一个ProdutoDAO实例的findObject方法获取的实体,这个实体已经被当前DatabaseContext跟踪了。这种情况下,其实不需要手动设置EntityState.Modified,EF会自动跟踪实体的属性变更,直接调用SaveChanges()就可以完成更新:
public Boolean update(T obj) { try{ context.SaveChanges(); // 实体已被跟踪,直接提交变更即可 return true; }catch (Exception e){ Debug.WriteLine("Update error: " + (e.InnerException?.Message ?? e.Message)); return false; } }
2. 优化上下文生命周期
当前你的GenericDAO每次实例化都会新建一个DatabaseContext,如果业务中多次创建DAO实例,可能会出现多个上下文跟踪同一实体导致的冲突。建议考虑用依赖注入来管理上下文的生命周期(比如每个请求用同一个上下文),或者确保同一业务操作中使用同一个DAO/上下文实例。
3. 完善异常处理
原来的代码直接访问e.InnerException.Message,如果InnerException为null会抛出空引用异常,改成e.InnerException?.Message ?? e.Message可以避免这个问题,同时保留更详细的错误信息。
修改完成后,再运行你的调用代码,就能看到控制台输出"update ok!",数据库里的Produto记录也会被正确更新啦。
内容的提问来源于stack exchange,提问作者FernandoPaiva

