C# 从列表中删除孤立嵌套实体后,如何删除它们?

C# 从列表中删除孤立嵌套实体后,如何删除它们?,c#,.net-core,entity-framework-core,C#,.net Core,Entity Framework Core,我正在使用.NETCore2.2为Angular8Spa构建后端。 我管理订单-每个订单都有一个IList。 我想使用实现一个简单的OrdersService,它只有一个更新方法,不需要了解任何业务规则 我有一个包含Orderobject的抽象OrderUpdateActionclass。该类有一个抽象的Do方法,该方法的每个实现都包含业务逻辑。Do返回更新的Orderobject My OrdersService只有一个UpdateOrderOrderUpdateAction orderUpd

我正在使用.NETCore2.2为Angular8Spa构建后端。 我管理订单-每个订单都有一个IList。 我想使用实现一个简单的OrdersService,它只有一个更新方法,不需要了解任何业务规则

我有一个包含Orderobject的抽象OrderUpdateActionclass。该类有一个抽象的Do方法,该方法的每个实现都包含业务逻辑。Do返回更新的Orderobject

My OrdersService只有一个UpdateOrderOrderUpdateAction orderUpdatemethod,它调用DOA,然后将更新后的订单交给DbContext,用于存储对Db的更改

实体

订单服务

这一切都很好,但当从订单的IList中删除订单行时,该订单行不会从数据库中删除-EF似乎只是通过在订单行null中设置OrderId来删除这些实体之间的“链接”

我知道,当多个“父”实体引用该订单行时,这种行为可能很有用,但这里的情况并非如此

有没有办法告诉EF删除这些孤立的订单行,或者我必须在更新后手动“清理”这些订单行


谢谢:

我认为您需要考虑在实体配置上设置DeleteBehavior。查看这篇文章,了解有关您的不同选项的信息:

确保您在DbContex中启用了级联删除,您可以添加如下内容

modelBuilder.Entity<OrderLine>().HasOne(x =>x.Order).WithMany().OnDelete(DeleteBehavior.Cascade);
到OnModelCreatingModelBuilder的正文modelBuilder

OrdersService只有一个更新方法,不需要 了解任何商业规则吗

我认为你把服务的职责和存储库的职责弄混了。CRUD操作通常由存储库处理,服务是维护应用程序业务逻辑的适当位置。因为您使用的是EF Core,所以不需要在其上构建存储库模式,因为它已经是一个存储库了,所以您只需向DbContext添加一些扩展方法,即可进行创建、更新或删除内容等琐碎操作。你可以看看这篇文章,看看EF Core给你的选项有多强大

你也可以看看这个


在传统的分层体系结构中,服务实际上是业务逻辑层的同义词。它是UI和数据之间的层。因此,所有业务规则都进入服务。数据层应该只理解基本的CRUD操作,UI层应该只处理表示DTO与业务对象之间的映射。

事实证明,我所要做的就是使OrderId Guid不可为空。默认情况下,删除的订单行将被删除

的链接很有帮助:

是否删除订单行或订单?如果删除订单行,为什么要将订单行中的OrderId设置为空。我只是删除订单行,我从不删除订单。您在ModelCreating中有配置吗?您的代码如此复杂,以致于执行诸如删除对象之间的关系这样的琐碎操作,有什么原因吗?它可以做得简单得多…对于我来说,像DeleteAction:OrderUpdateAction这样的东西毫无意义,因为Delete和Update是两个完全分离的东西,我会说它打破了一些坚实的原则。这非常有用。非常感谢。我真愚蠢,没有正确阅读文档。汉克斯:那么你会为每一个操作指定专门的方法吗?例如:RemoveOrderLineFromOrderGuid orderId、Guid orderLineId、UpdateOrderLineAmountToGuid orderLineId、int newAmount等。如果您只想从订单中删除订单行,扩展方法将只是,例如,在Order对象上直接调用RemoveOrderLineorderLineId,如var yourOrder=context.Order.Singlex=>x.Id=>givenId;yourOrder.RemoveOrderLinegivenOrderLineId;您可以在某个服务中的某个方法体中执行所有这些操作。请记住,这是一种非常现代的方法,您可以找到许多仍然喜欢使用老式存储库模式的人
public abstract class OrderUpdateAction
{
     public Order Order { get; set; }
     public abstract Order Do();
}

public class DeleteAction : OrderUpdateAction
{

     public Guid OrderLineId { get; set; }

     public override Order Do()
     {

       if (Order.OrderLines.FirstOrDefault(ol => ol.Id == OrderLineId) != null)
       {
           Order.OrderLines.Remove(Order.OrderLines.FirstOrDefault(ol => ol.Id == OrderLineId));
       }

       return Order;
     }
}
public async Task<Order> UpdateOrder(OrderUpdateAction orderUpdate)
{
     var order = orderUpdate.Do();

     _dbContext.Orders.Update(order);

     await _dbContext.SaveChangesAsync();

     [Caching, logging, etc]

     return order;
}

modelBuilder.Entity<OrderLine>().HasOne(x =>x.Order).WithMany().OnDelete(DeleteBehavior.Cascade);