C# LINQ联表后SQL数据无法更新问题求助
问题分析与解决方案
核心问题
你当前代码中通过select new TestJ()创建的对象是非EF跟踪的独立对象——EF只会监控从context.StatusDocs或context.get_test直接查询出来的原始实体,对这种手动new出来的对象,EF不会记录任何变更,所以调用SaveChanges()不会同步到数据库。
解决方案
根据TestJ的类型(DTO/EF实体),分两种处理方式:
情况1:TestJ是数据传输对象(DTO,无EF DbSet映射)
需要分别查询两张表的原始实体,更新实体字段后再保存:
// PUT api/<TestJoinController>/5 [HttpPut("{id}")] public ActionResult Put(int id, [FromBody] TestJ gestor) { // 查询两张表的原始跟踪实体 var statusDoc = context.StatusDocs.FirstOrDefault(p => p.Id == id); var testEntity = context.get_test.FirstOrDefault(c => c.Id == id); if (statusDoc == null || testEntity == null) { return NotFound(); } // 使用传入的DTO数据更新实体字段 statusDoc.SDocNumber = gestor.SDocNumber; statusDoc.StatusDoc = gestor.StatusDoc; testEntity.Name = gestor.Name; testEntity.Address = gestor.Address; testEntity.Developer = gestor.Developer; // 保存所有变更到数据库 context.SaveChanges(); // 返回更新后的DTO数据 var updatedResult = new TestJ { Id = id, SDocNumber = statusDoc.SDocNumber, StatusDoc = statusDoc.StatusDoc, Name = testEntity.Name, Address = testEntity.Address, Developer = testEntity.Developer, }; return Ok(updatedResult); }
情况2:TestJ是EF实体类(已在DbContext中配置DbSet)
直接查询跟踪的实体,修改后保存即可:
// PUT api/<TestJoinController>/5 [HttpPut("{id}")] public ActionResult Put(int id, [FromBody] TestJ gestor) { var existingEntity = context.TestJs.FirstOrDefault(t => t.Id == id); if (existingEntity == null) { return NotFound(); } // 批量映射字段(需保证TestJ字段与实体字段匹配) context.Entry(existingEntity).CurrentValues.SetValues(gestor); context.SaveChanges(); return Ok(existingEntity); }
关键注意事项
- EF仅跟踪从
context.DbSet直接查询的实体,手动实例化的对象不会被监控 - 区分DTO和EF实体:DTO用于前后端数据传输,EF实体用于数据库操作,不要混用
- 可以使用AutoMapper等工具简化DTO与实体之间的字段映射,减少重复代码
内容的提问来源于stack exchange,提问作者bearrrrr
相关产品推荐
相关产品推荐

