Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF code first: How to delete a row from an entity's Collection while following DDD?

So here's the scenario:

DDD states that you use a repository to get the aggregate root, then use that to add/remove to any collections it has.

Adding is simple, you simple call .Add(Item item) on the Collection you wish to add to. A new row is added to the database when you save. However, deleting is different - calling .Remove(Item item) doesn't remove the item from the database, it simply removes the foreign key. So while, yes, it is technically no longer part of the collection anymore, it's still in the database.

Reading around, the only solution is to delete it using the data context. But according to DDD the domain object shouldn't be aware of the data context so therefore deleting will have to be done outside of the domain.

What is the right way to go about this? Or Is leaving the database full of orphans acceptable (perhaps running a routine to clear them out)?

like image 313
edgarian Avatar asked Dec 02 '11 17:12

edgarian


People also ask

How do I delete a row in Entity Framework?

In Connected Scenario, you can use the Remove or RemoveRange method to mark the record as Deleted . In Disconnected Scenario, you can attach it to the context and set its state as Deleted . Calling SaveChanges will send the delete query to the database.

What is Cascade delete in EF core?

Cascade delete in the database Many database systems also offer cascading behaviors that are triggered when an entity is deleted in the database. EF Core configures these behaviors based on the cascade delete behavior in the EF Core model when a database is created using EnsureCreated or EF Core migrations.

How do I enable cascade delete in Entity Framework?

Cascade delete is enabled by default in Entity Framework for all types of relationships such as one-to-one, one-to-many and many-to-many.


2 Answers

I've solved this problem in the application I'm currently working on by using domain events; a DDD concept Eric Evans said should have been in his book.

While domain objects aren't allowed to know about the object context, an IDomainEventHandler is - I've therefore got a DomainObjectDeletionHandler which deletes 'removed' objects from the object context before control returns to my application layer and the changes are saved.

For more information, I've written a blog about my implementation of domain events and how I approached hooking everything together.

Hope that helps :)

Edit

For example, if you have an Order class which has an OrderItems collection of type OrderItem:

public class Order
{
    // Other stuff

    public void RemoveOrderItem(int orderItemId)
    {
        var orderItemToRemove = OrderItems.First(oi => oi.Id == orderItemId)

        OrderItems.Remove(orderItemToRemove);

        DomainEvents.Raise(new OrderItemRemoved(orderItemToRemove));
    }
}
like image 72
Steve Wilkes Avatar answered Oct 02 '22 23:10

Steve Wilkes


When removing a child entity from a collection, EF will leave it as orphan, removing just the foreign key.

If you don't want to explicitly remove it using the DbContext, you can use what it is called "Identifying Relationship" (http://msdn.microsoft.com/en-us/library/ee373856.aspx at the bottom).

The trick is to set a composite primary key on the child including the parent's primary key.

Once you do that, when removing the entity from the parent's collection, it will be removed from the table as well.

like image 35
Jorge Fioranelli Avatar answered Oct 02 '22 23:10

Jorge Fioranelli