ASP.NET MVC更新数据库时Image字段数据丢失问题如何解决?
问题原因
- 你在Edit方法的
[Bind]特性中仅指定了绑定Id和ImageDescription两个字段,因此框架构造出来的gallery对象的Image属性会被赋值为默认值null。 - EF Core的
Update()方法会将传入实体的所有字段标记为已修改,执行保存时会把所有字段的值(包括为null的Image字段)同步写入数据库,最终导致原有Image字段被覆盖为空。
解决方法
方法1:先查询原有实体再更新指定字段(最稳妥,推荐)
先从数据库查询出已存在的Gallery实体,仅修改需要更新的ImageDescription字段后保存,不会影响其他字段的值。
代码示例:
public async Task<IActionResult> Edit(int id, [Bind("Id,ImageDescription")] Gallery gallery) { if (id != gallery.Id) { return NotFound(); } if (ModelState.IsValid) { try { // 先查询现有实体 var existGallery = await _context.Galleries.FindAsync(id); if (existGallery == null) { return NotFound(); } // 仅更新需要修改的字段 existGallery.ImageDescription = gallery.ImageDescription; // 不需要调用Update,上下文会自动跟踪实体变更 await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!GalleryExists(gallery.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } return View(gallery); }
方法2:手动标记仅更新指定字段(不需要提前查询,性能更高)
将传入的gallery实体附加到上下文,仅标记ImageDescription为已修改,EF执行更新时只会修改该字段。
代码示例:
public async Task<IActionResult> Edit(int id, [Bind("Id,ImageDescription")] Gallery gallery) { if (id != gallery.Id) { return NotFound(); } if (ModelState.IsValid) { try { // 附加实体到上下文,此时所有字段默认标记为未修改 _context.Attach(gallery); // 仅标记ImageDescription为已修改 _context.Entry(gallery).Property(x => x.ImageDescription).IsModified = true; await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!GalleryExists(gallery.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } return View(gallery); }
不推荐通过在
[Bind]特性中添加Image字段解决问题,该方案需要在编辑视图中添加隐藏字段存储Image原值,会增大请求体积,且字节数组序列化传输容易出错。
内容的提问来源于stack exchange,提问作者idk123123
相关产品推荐
相关产品推荐

