Delete Child Object From Aggregate Root With EF Repository

907 Views Asked by At

My original question is here.

Below is my updated code.

Public Function StockTransferItemRemove(removeRequest As StockTransferItemRequest) As StockTransferItemResponse Implements IStockTransferService.StockTransferItemRemove
        ' create your objects
        Dim removeResponse = New StockTransferItemResponse
        Dim stockTransfer As New StockTransfer
        Dim stockTransferItem As New StockTransferItem

        Try

            ' get the aggregate root
            stockTransfer = _stockTransferRepository.FindBy(removeRequest.StockTransferID).FirstOrDefault

            stockTransfer.RemoveItem(removeRequest.StockTransferItemView.Id)

            _stockTransferRepository.Save(stockTransfer)

            Dim count As Integer = _uow.WMSCommit()

            If (count > 0) Then
               ' the object was saved succesfully
                    removeResponse.Success = True
            Else
               ' the object was not saved successfully
               removeResponse.BrokenRules.Add(New BusinessRule(String.Empty, String.Empty, Tags.Messages.Commit_Failed))
            End If


        Catch ex As Exception
            ' an unexpected error occured
            removeResponse.BrokenRules.Add(New BusinessRule(String.Empty, String.Empty, ex.Message))
        End Try

        Return removeResponse
    End Function

When the unit of work tries to commit it produces the following error message.

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.

I know that when I use StockTransfer.RemoveItem() that it removes the item from the collection but it keeps the record in the database, which is why I am receiving the error.

Is there a way of removing the child object from an aggregate Root and persisting the aggregate root?

4

There are 4 best solutions below

1
On

Im sorry for the unclear code but im a C# guy so trying to find my way in VB Code. You should use the .Clear() option on the entities link which you want to clear.

Example:

Company <> Employees

Company.Emplyees.Clear() removes all the records in the relation table.

0
On

Did you find a good solution? I have created a solution using a ParentAttribute and extending the DbContext SaveChanges or ValidateEntity. You can find my solution here.

0
On

The answer might be a little late but, this extension method on my data context called DataContext (which inherits from DbContext) worked for me using EF4.3.

public static void Delete<TEntity>(this DataContext context, IEnumerable<TEntity> entities) where TEntity : class, new()
{
    foreach (var entity in entities)
    {
        context.Delete(entity);
    }
}

public static void Delete<TEntity>(this DataContext context, TEntity entity) where TEntity : class, new()
{
    var obj = context.Entry(entity);
    if (obj.State == System.Data.EntityState.Detached)
    {
        context.Set(typeof(TEntity)).Attach(obj.Entity);
    }
    context.Set(typeof(TEntity)).Remove(obj.Entity);
}

And the data context class just for completeness.

public class DataContext : DbContext
{
    public DbSet<MyPOCO> POCOs { get; set; }

    ...
}
1
On

Thats an issue im having too. I dont know the pure solution, but i always have to delete it in the ef context manualy before saving changes. In your repository method for save You should check for entities which are in the ef context but not in aggregates collection and remove them from the dbset on the context.