使用Entity Framework更新记录时出现新增行而非更新的问题
问题诊断与修复方案
嘿,我一眼就瞅出问题所在了——你代码末尾调用的db.Datos_Personales.Add(datos);是罪魁祸首!这个方法是告诉EF要新增一条实体记录,而不是更新已存在的行。另外你的代码里还有些冗余操作,我帮你整理并修正:
为啥会变成新增而不是更新?
当你通过db.Datos_Personales.Where(d => d.UserId == UserId && d.Id == ID).First();获取到实体时,这个实体已经被EF的上下文跟踪了。此时你修改它的属性,EF会自动记录这些变更,调用db.SaveChanges();时就会生成UPDATE语句。但你最后加了Add方法,直接把这个实体的状态改成了“新增”,EF自然就执行INSERT而非UPDATE了。
另外你一开始把所有Datos_Personales都读到内存里(ToList())还循环了一遍,这完全是多余的,纯纯浪费性能,完全可以删掉这部分代码。
修正后的完整代码
public void Update_Datos(int ID) { int UserId = Convert.ToInt16(Session["UserId"].ToString()); using (var db = new Entities()) { // 直接查询目标实体,EF会自动跟踪它的变化 var datos = db.Datos_Personales.FirstOrDefault(d => d.UserId == UserId && d.Id == ID); // 先检查实体是否存在,避免空引用炸锅 if (datos != null) { datos.Fecha_de_nacimiento = Convert.ToDateTime(Fecha_de_nacimiento.Text); datos.Nombre_Completo = txt_Nombre_Completo.Text; datos.Identificacion = txt_Identificacion.Text; datos.Estado_civil = ddEstadoCivil.SelectedValue; datos.Telefono = txt_num_telefono.Text; datos.Departamento = ddDepartamento.SelectedValue; datos.Nacionalidad = Country.SelectedValue; datos.Salario_min_aceptado = ddSalario_min_aceptado.SelectedValue; datos.Titulo = txt_Titulo.Text; datos.Descripcion_Profesional = txt_Descripcion_Profesional.Text; // 这里不需要重新给UserId赋值,查询条件已经保证了实体的UserId是正确的 // datos.UserId = Convert.ToInt16(UserId); // 直接保存变更即可,不需要Add! db.SaveChanges(); } else { // 这里可以根据需求处理记录不存在的情况,比如抛异常或者给用户提示 throw new InvalidOperationException($"未找到UserId为{UserId}且Id为{ID}的个人数据记录"); } } }
几个关键提醒
- 删掉
Add方法:更新已被上下文跟踪的实体时,绝对不需要调用Add,否则会强制变成新增操作。 - 别做无意义的全表查询:
db.Datos_Personales.ToList()完全没必要,直接通过条件定位目标实体,既省内存又快。 - 加空值检查:
FirstOrDefault可能返回null,一定要先判断实体是否存在,不然修改属性时会触发空引用异常。 - 避免重复赋值:查询条件里已经包含了
UserId匹配,所以实体的UserId本来就是正确的,没必要再重新设置。
这样修改后,EF就会正确生成UPDATE语句去更新你指定的行,而不会再新增记录啦。
内容的提问来源于stack exchange,提问作者Rodolfo Calvo
相关产品推荐
相关产品推荐

