实体框架:删除另一个实体时删除实体的最佳方式

本文关键字:实体 删除 最佳 方式 另一个 框架 | 更新日期: 2023-09-27 18:19:06

我有订单,订单有行。当删除最后一个订单行时,订单也应被删除。我正在努力寻找最好的地方。

开发人员只需调用上下文。删除(订单行(以删除该行。因此,如果这是最后一行,则删除订单的逻辑应该在删除调用中。

当前的想法是创建一个继承自 DbSet 的 OrderLineDbSet 并覆盖那里的 Remove 调用。但问题是,我无法访问数据上下文,因为依赖注入在这里不起作用......

我做了一些挖掘 https://github.com/mono/entityframework/blob/master/src/EntityFramework/DbSet.cs 但我无法弄清楚。

我尝试的最后一个代码是这样的:

public class OrderLineDbSet : DbSet<OrderLine>
{
    CourseContext context { get; set; }
    public OrderLineDbSet(CourseContext context)
    {
        this.context = context;
    }
    public override OrderLine Add(OrderLine entity)
    {
        return base.Add(entity);
    }
    public override OrderLine Remove(OrderLine entity)
    {
        Order order = entity.Order;
        var line = base.Remove(entity);
        if (!order.OrderLines.Any())
        {
            context.Orders.Remove(order);
        }
        return line;
    }
}

实体框架:删除另一个实体时删除实体的最佳方式

问题是您正在尝试将业务逻辑推送到数据访问层。通常,你有一个类,它实现一些业务逻辑,例如:

public class OrdersService
{
    public void RemoveOrderLine(OrderLine orderLine)
    {
        // get db context (or some repository)
        var context = GetDbContext();
        // attach or load entities, etc.
        // this is _business logic_;
        // it is not natural for relational database;
        // it is not related to db context or repositiory
        context.OrderLines.Remove(orderLine);
        if (!order.OrderLines.Any())
        {
            context.Orders.Remove(order);
        }        
    }
}

换句话说。想象一下,在最后一行被删除后,用户必须收到短信,该订单也被删除了。这是一个与数据库完全无关的操作。你想把短信发送放在DbSet吗?

这应该使用映射进行设置,并让实体框架删除整个对象图。

public class MyContext : DbContext
{
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderLine> Lines { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Order>()
                    .HasMany(a => a.Lines)
                    .WithRequired(b => b.Orders)
                    .WillCascadeOnDelete();
    }
}