我需要从实体框架中删除集合



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

找到了一些部分解决方案,但没有什么可以指导我找到一个有效的解决方案。我可以很容易地为集合添加值;感谢任何人的帮助。

我有以下内容:

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

我从你的问题中推断出,你有一个接受更新的路由工具对象的方法,该对象包含更新的工具服务集合。您希望更新该工具及其关联的服务,以便添加或更新该工具中的任何新服务,并删除数据库中不再位于传入集合中的任何现有工具。。

如果是这种情况,则需要将提供的数据版本与数据库版本的数据进行比较。对于本例,我不使用您的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服务时,我的建议是避免像这样的大型更新操作,而是将应用程序构造为执行更多的原子操作,例如将为给定工具添加和删除服务作为一种独特的操作,如果希望将整个相关操作提交到数据状态或在更高级别放弃,请使用数据的持久化副本(即缓存实例(。这可以帮助保持消息大小较小,并且服务器代码更加紧凑&担心一项责任。执行这些大型操作的风险在于,传入的数据必须代表数据状态的完整画面,否则您可能会删除/清除不想要的数据。例如,如果您稍后希望优化代码,以便只通过有线发送添加和更新的服务,而不是未更改的服务(以减小消息大小(,则上述代码将无法工作,因为它会删除任何未发送的内容。

最新更新