【问题标题】:Update, create or delete EF Core更新、创建或删除 EF Core
【发布时间】:2019-08-14 22:56:29
【问题描述】:

我有一个 API,我希望能够在其中执行 PUT 请求,并在其中发布带有 Blocks 数组的 Plan。目前,它会自动添加新的 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; }
}

控制器动作:

[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();

    _context.Update(plan);

    _context.SaveChanges();

    return NoContent();
}

我将如何实现这一点? EF中是否有启用此功能的设置?

我正在寻找一个通用的解决方案,因为会有更多的集合和模型需要相同的功能。我不想为每个控制器/动作都编写这个程序。

我在 .net core 2.2 上使用 Entity Framework Core

【问题讨论】:

  • 你能在更新Plan实体的地方添加代码示例吗?
  • @Fourat 当然,我添加了它
  • 在类似的情况下,我必须创建一个 UpdateEntity 方法来获取数据库实体和请求实体。 here is a link to the more detailed answer

标签: .net-core entity-framework-core


【解决方案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();
}

【讨论】:

  • 我同意这将是简单的手动解决方案,但是我正在寻找更通用的解决方案,因为会有更多的集合和更多的模型。
【解决方案2】:

以下解决方案更清洁。

[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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    相关资源
    最近更新 更多