【问题标题】:I need to erase collection from Entity Framework我需要从实体框架中删除集合
【发布时间】:2022-01-13 06:43:08
【问题描述】:

我可以添加,但不能删除集合中的任何项目 - 无法删除。

找到了一些部分解决方案,但没有任何东西可以指导我找到可行的解决方案。我可以轻松地将值添加到集合中;感谢您的帮助。

我有以下几点:

[HttpPut("updateSOJ4")]
public IActionResult UpdateSOJ4([FromBody] Routing_Tool_SOJ4 Routing_Tool_SOJ4)
{
    Routing_Tool_SOJ4 request = new Routing_Tool_SOJ4();
    request.Id = Routing_Tool_SOJ4.Id;
    request.Routing_Tool_Services = Routing_Tool_SOJ4.Routing_Tool_Services;
    request.Routing_ToolId = Routing_Tool_SOJ4.Routing_ToolId;

    _repository.UpdateSOJ4(request);

    return Ok(request);
}

这是我尝试不同解决方案的地方,但我仍然卡住了:

public void UpdateSOJ4(object routing_Tool_SOJ4)
{
    // var missingItem = _context.Routing_Tool_Service.Where(i => i.Routing_Tool_SOJ4Id == _context.Routing_Tool_SOJ4.Id).First(); -- DOES NOT WORK
    _context.Update(routing_Tool_SOJ4).State = EntityState.Modified;
    _context.SaveChanges();
}

这是数据库结构:

public class Routing_Tool_SOJ4
{
    [Key]
    [Required]
    public int Id { get; set; }
    
    public int Routing_ToolId { get; set; }
    
    [ForeignKey("Routing_ToolId")]
    public virtual Routing_Tool Routing_Tool { get; set; }
    
    public virtual ICollection <Routing_Tool_Service> Routing_Tool_Services { get; set; }
} 

收藏:

public class Routing_Tool_Service
{
    [Key]
    [Required]
    public int Id { get; set; }

    public string ServiceName { get; set; }

    [Required]
    [ForeignKey("Routing_Tool_SOJ4Id")]
    public int Routing_Tool_SOJ4Id { get; set; }
}

【问题讨论】:

  • 你检查过这个答案 - stackoverflow.com/a/22381952/1461862 吗?
  • 是的,我有。集合作为 JSON obj 发送,我看不到如何分配它来擦除相关项目。
  • 如果我理解正确,您需要将 JSON 数组反序列化为您自己的类型/集合才能删除某些项目 - stackoverflow.com/questions/16856846/…
  • 这个方法 public void UpdateSOJ4(object routing_Tool_SOJ4) 是否收到所有新项目或需要删除的项目?
  • 它得到一个项目。如果该项目存在,则获取更新,如果不存在,则将其删除。我读过的最接近的解释stackoverflow.com/questions/51331850/…,但是“(i => i.Routing_Tool_SOJ4Id == _context.Routing_Tool_SOJ4.Id)”失败了。

标签: c# entity-framework-core ef-core-2.0


【解决方案1】:

我从您的问题中得出的结论是,您有一个接受更新的路由工具对象的方法,该对象包含更新的工具服务集合。您想要更新该工具及其相关服务,以便添加该工具中的任何新服务,否则将进行更新,并且应删除数据库中不再在传入集合中的任何现有工具..

如果是这种情况,您需要将提供的数据版本与数据的数据库版本进行比较。对于此示例,我 使用您的 Repository 实例,因为我不知道它是如何实现的。通常应该避免这种模式,除非有很好的理由使用它。

[HttpPut("updateSOJ4")]
public IActionResult UpdateSOJ4([FromBody] Routing_Tool_SOJ4 updatedRoutingTool)
{
    using (var context = new AppDbContext())
    {
        // Get tool and services from DB.
        var existingRoutingTool = context.Routing_Tool_SOJ4s
            .Include(x => x.Routing_Tool_Services)
            .Single(x => x.Id == updatedRoutingTool.Id);

        // Copy values that can be updated from the updatedRoutingTool to existingRoutingTool.
        // ...

        var updatedServiceIds = updatedRoutingTool.Routing_Tool_Services
            .Select(x => x.Id)
            .ToList();
        var existingServiceIds = existingRoutingTool.Routing_Tool_Services
            .Select(x => x.Id)
            .ToList();
        var serviceIdsToRemove = existingServiceIds
            .Except(updatedServiceIds)
            .ToList();
         
        foreach (var service in updatedRoutingTool.Routing_Tool_Services)
        {
            var existingService = existingRoutingTool.Routing_ToolServices
                .SingleOrDefault(x => x.Id == service.Id);
            if (existingService == null)
                existingRoutingTool.Routing_Tool_Services.Add(service);
            else
            {
                 // Copy allowed values from service to existingService
            }
        }

        if(serviceIdsToRemove.Any())
        {
            var servicesToRemove = existingRoutingTool.Routing_Tool_Services
                .Where(x => serviceIdsToRemove.Contains(x.Id))
                .ToList();
            foreach(var serviceToRemove in servicesToRemove)
                existingRoutingTool.Routing_Tool_Services.Remove(serviceToRemove);
        }

        context.SaveChanges();
    }

    return Ok(request);
}

通常情况下,DbContext 或工作单元会被注入到您的控制器中,或者逻辑会被移交给服务。此示例使用带有 DbContext 的 using 块来概述操作的最小可行流程。

基本上加载当前数据状态,将其与提供的状态进行比较以确定需要添加、更新或删除的内容。

一般而言,对于 RESTful Web 服务,我的建议是避免像这样的大型更新操作,而是构建应用程序以执行更多原子操作,例如将给定工具的服务添加和删除作为不同的操作,使用如果您希望整个相关操作被提交到数据状态或在更高级别被放弃,则数据的持久副本(即缓存实例)。这可以帮助保持较小的消息大小,并使服务器代码更紧凑并担心单一责任。执行这些大型操作的风险在于传入的数据必须代表数据状态的完整图片,否则您最终可能会删除/清除您不想要的数据。例如,如果您稍后想要优化您的代码,以便仅通过线路发送添加和更新的服务,而不是未更改的服务(以减少消息大小),上述代码将无法正常工作,因为它会删除任何未发送的内容。

【讨论】:

  • 我喜欢这个“我的建议是避免像这样的大型更新操作,而是构建应用程序以执行更多原子”也许我应该寻找一种不同的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多