要素数が増減する場合は、以下のようにして処理を行うことができます。
[HttpPut("{id}")]
public async Task<IActionResult> Put(int id, [FromBody] Parent parent)
{
if (id != parent.Id)
{
return BadRequest();
}
var existingParent = await _context.Parents
.Include(p => p.Children)
.SingleOrDefaultAsync(p => p.Id == id);
if (existingParent == null)
{
return NotFound();
}
existingParent.Name = parent.Name;
// 子データの更新
var updatedChildren = new List<Child>();
foreach (var child in parent.Children)
{
if (child.Id == 0)
{
// 新しい子データを追加する場合
var newChild = new Child
{
Name = child.Name,
ParentId = parent.Id
};
updatedChildren.Add(newChild);
}
else
{
// 既存の子データを更新する場合
var existingChild = existingParent.Children.SingleOrDefault(c => c.Id == child.Id);
if (existingChild == null)
{
return NotFound();
}
existingChild.Name = child.Name;
updatedChildren.Add(existingChild);
}
}
// 削除された子データを検出する
var deletedChildren = existingParent.Children.Where(c => !updatedChildren.Any(uc => uc.Id == c.Id)).ToList();
foreach (var deletedChild in deletedChildren)
{
existingParent.Children.Remove(deletedChild);
}
// 新しい子データを追加する
foreach (var newChild in updatedChildren.Where(c => c.Id == 0))
{
existingParent.Children.Add(newChild);
}
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ParentExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
上記の例では、子データの更新処理に加えて、削除された子データと追加された子データを検出して、それぞれの処理を行っています。削除された子データは、更新された子データのリストに含まれていない既存の子データとして検出されます。これらの子データを検出した後、親クラスのChildrenプロパティからこれらの子データを削除します。一方、追加された子データは、更新された子データのリストに含まれているが、親クラスのChildrenプロパティには含まれていない子データとして検出されます。これらの子データを検出した後、親クラスのChildrenプロパティにこれらの子データを追加します。
https://pie-scarer-6c1.notion.site/PostMan-Tokyo-Meetup-8-d46008c973be4c06bb9f6a510666c50f?pvs=4