我已经使用存储库模式和 DTO 在我的项目中实现了更新功能。
每当我更新记录时,我都会收到成功消息,但记录被删除!
以下是一些可能有用的日志:
The 'RCJY' entity with key '{Id: 1002}' tracked by 'ApplicationDbContext' changed state from 'Unchanged' to 'Modified'.
dbug: 6/4/2023 13:55:26.384 CoreEventId.SaveChangesStarting[10004] (Microsoft.EntityFrameworkCore.Update)
SaveChanges starting for 'ApplicationDbContext'.
dbug: 6/4/2023 13:55:26.384 CoreEventId.DetectChangesStarting[10800] (Microsoft.EntityFrameworkCore.ChangeTracking)
DetectChanges starting for 'ApplicationDbContext'.
dbug: 6/4/2023 13:55:26.387 CoreEventId.ForeignKeyChangeDetected[10803] (Microsoft.EntityFrameworkCore.ChangeTracking)
The foreign key property 'RCJY.RootId' was detected as changed from '65' to '(null)' for entity with key '{Id: 1002}'.
dbug: 6/4/2023 13:55:26.400 CoreEventId.CascadeDeleteOrphan[10003] (Microsoft.EntityFrameworkCore.Update)
An entity of type 'RCJY' with key '{Id: 1002}' changed to 'Deleted' state due to severed required relationship to its parent entity of type 'Root'.
控制器:
[HttpPut("{id}")]
public async Task<IActionResult> PutMOD(int id, UpdateMODDto updateMODDto)
{
// Check IDs equality
if (id != updateMODDto.Id)
{
return BadRequest($"Not Found11 {id} {updateMODDto.Id}");
}
var entity = await _modRepository.GetAsync(id);
if (entity == null)
{
throw new Exception($"MOH ID {id} not found");
}
_mapper.Map(updateMODDto, entity);
try
{
await _modRepository.UpdateAsync(entity);
}
catch (DbUpdateConcurrencyException)
{
if (!await MODExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
存储库:
public async Task UpdateAsync(T entity)
{
_context.Update(entity);
await _context.SaveChangesAsync();
}
DTO:
public class UpdateMODDto : MODDto
{
public int Id { get; set; }
}
我们看不到
updateMODDto
的属性,但从日志来看,记录的 RootId
列正在从 65 更新为 null。
有可能没有指定
updateMODDto.RootId
吗?
在这种情况下, _mapper.Map(updateMODDto, entity);
会将 entity.RootId
设置为
空。
另外从日志来看,如果与任何父级都没有关系(这意味着:如果 RootId 为 null),则实体将被删除(因为 CascadeDeleteOrphan)。
如果上述假设正确,我可以看到以下可能的解决方案:
您应该更改数据库以接受 RootId null 的记录(如果可以有没有根/父级的记录,具体取决于实际用例)
您必须确保
updateMODDto
对象实际上包含非空 RootId 属性。
您可能想要实现一个逻辑来为实体生成 RootId,并在调用映射器后设置它。