Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleting a child object of an aggregate root in Entity framework

This might be asked before but I can't seem to find a solution on the site so here we go:

Here is an oversimplified version of my domain model. I have 2 classes representing 2 tables in the database:

public Class Person
{
    public int Id { get; set;}
    public string Name { get; set;}
    public virtual List<Contact> Contacts { get; set;}

    public void AddContact(string value) 
    {
        //some validation code
        Contacts.Add(new Contact(value));
    }

    public void DeleteContact(Contact contact) 
    {
        //some validation code
        Contacts.Remove(contact);
    }
}

public Class Contact
{
    public int Id { get; set;}
    public string Value { get; set;}
    public virtual Person Person { get; set;}
    public int PersonId { get; set;}
}

Now Person is my aggregate root here. I am trying to follow the DDD principal by only making the repository for the aggregate root. Adding contact works fine.

The problem I have is when deleting the contact. It gives the error:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

Is there anyway past it. If the relation property is non-nullable shouldn't entity framework automatically delete the contact.

Now I know that deleting from the collection is not the same as deleting it from the context but I don't want to reference DbContext from my domain model.

I only have PersonRepository.

Kindly provide a solution or help me understand if I am getting any concept wrong.

like image 929
Muhammad Ibraheem Avatar asked Oct 16 '25 11:10

Muhammad Ibraheem


1 Answers

That's a common problem when doing DDD with EF. Two solutions worked well for me so far:

  1. Return the removed instance from your DeleteContact method. The method is most probably called from an application service which holds a repository. You can then use it to remove the instance from DbContext.

  2. If you use domain events you can use one to notify others about contact removal. You could then place a handler for this event in the infrastructure layer which would remove the contact from DbContext.

like image 125
dmusial Avatar answered Oct 18 '25 23:10

dmusial