2

My Blazor application uses Web API to get its data. I'm using EF Core and access data via generic Repository. I have entities with parent-child relationship where the child entity is nested in a collection on the parent entity. My code looks like this:

public class Parent
{
    [Required]
    public long Id { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual ICollection<Child> Children { get; set; }
}

public class Child
{
    [Required]
    public long Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public long ParentId { get; set; }
    public Parent Parent { get; set; }
}

// Repository - generic update method
public virtual async Task<TEntity> UpdateAsync(TEntity entity)
{
    if (entity == null)
    {
        throw new ArgumentNullException($"{nameof(AddAsync)} entity must not be null");
    }

    try
    {
        DbContext.Update(entity);
        await DbContext.SaveChangesAsync();

        return entity;
    }
    catch (Exception ex)
    {
        throw new Exception($"{nameof(entity)} could not be updated: {ex.Message}");
    }
}

// Controller - update for Parent
[HttpPut("{id}")]
public async Task<IActionResult> PutParent(long id, Parent parent)
{
    if (id != parent.Id)
    {
        return BadRequest();
    }
    try
    {
        await Repository.UpdateAsync(parent);
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!ParentExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

My issue is when I remove items from the Children collection. I'd expect them to get deleted, but since the update is disconnected EF Core apparently doesn't recognize this and doesn't delete them.

I have found some ways to make my application work as intended, but all of them are what I would call "workarounds".

One of them is to add an entity-specific repository that handles update differently, looks up the missing rows from the database and then marks them for deletion (see Entity Framework Core, deleting items from nested collection)

Although this solution worked for me, I'd like to find some solution that would support this behavior for my application on a base level without me needing to support it via type-specific repository for each of my entities.

I've seen a suggestion to use some "clever orphan handling" like in Can EF automatically delete data that is orphaned, where the parent is not deleted?, but I've been unable to come up with an equivalent solution for my case in EF Core. Another suggestion was to use Identifying Relation like in Can EF automatically delete data that is orphaned, where the parent is not deleted?, but I've been unable to make this suggestion work either.

I think I must be doing something totally wrong since it seems strange to me that this expected behavior should be something supported out of the box by just setting some option on or off in my DbContext.

Any help would be greatly appretiated.

Duken.Jr
  • 86
  • 5
  • 2
    There is no out of the box generic solution so far. I haven't tried it, but [EF Core Tools & Extensions](https://learn.microsoft.com/en-us/ef/core/extensions/) page contains a link to extension library called [Detached Mapper](https://learn.microsoft.com/en-us/ef/core/extensions/#detached-mapper) (*"A DTO-Entity mapper with composition/aggregation handling (similar to GraphDiff). For EF Core: 3, 5"*) which might help (GraphDiff was de facto standard for EF6) – Ivan Stoev Mar 20 '21 at 08:33
  • what approach did u follow while u are creating your database. if u followed the code-first approach,u can define a action while u are deleting your data. there is a options such as like cascade,no action,restrict u can click that [link][1] [1]: https://www.learnentityframeworkcore.com/configuration/fluent-api/ondelete-method – BerkGarip Mar 20 '21 at 12:37
  • Detached Mapper sounds interresting, I'll have a look. Delete behavior is not the issue here since the parent doesn't get deleted, just the children from the nested collection. – Duken.Jr Mar 20 '21 at 19:28

0 Answers0