我有一个API,我希望能够发出一个PUT
请求,并在其中发布一个Plan
数组。现在,它会自动添加新的Blocks
条目并更新现有的条目,但是如果帖子中缺少这些条目,它将不会删除。
这些是模型:
Block
以及控制器动作:
public class Plan
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Block> Blocks { get; set; }
}
public class Block
{
public int Id { get; set; }
public string Name { get; set; }
public int PlanId { get; set; }
public Plan Plan { get; set; }
}
我将如何实施呢? EF中是否有启用此功能的设置?
我正在寻找通用解决方案,因为将会有更多需要相同功能的集合和模型。我不想为每个控制器/动作都进行编程。
我正在.net core 2.2上使用Entity Framework Core
答案 0 :(得分:1)
由于您保留了主体实体(在您的情况下为Plan
),因此您应手动删除已删除的子实体(Blocks
):
[HttpPut]
public ActionResult Update(Plan plan)
{
if (plan?.Id == null) return BadRequest();
var plans = _context.Plans.Count(p => p.Id == plan.Id);
if (plans != 1) return NotFound();
var oldBlocks = _context.Blocks.Where(b => b.PlanId == plan.Id);
foreach(var block in oldBlocks)
{
if (!plan.Blocks.Any(b => b.Id == block.Id))
_context.Entry(block).State = EntityState.Deleted;
}
_context.Update(plan);
_context.SaveChanges();
return NoContent();
}
答案 1 :(得分:0)
以下解决方案要干净得多。
[HttpPut]
public ActionResult Update(Plan plan)
{
if (plan?.Id == null) return BadRequest();
var oldPlan = _context.Plans
.Where(p => p.Id == plan.Id)
.Include(p => p.Blocks)
.FirstOrDefault();
if (oldPlan == null) return NotFound();
oldPlan.Name = plan.Name;
oldPlan.Blocks = plan.Blocks; //This will wipe out all the existing blocks and replace with new ones. If blocked are null it will just deleted all the existing blocks.
_context.SaveChanges(); //No need of _context.Update(plan);
return NoContent();
}