0

I have the following method in my controller:

[HttpPost]
public async Task<ActionResult<ChartsCategoryDto>> PostChartsCategory(ChartsCategoryDto chartsCategory)
{
    try
    {
        var category = _mapper.Map<ChartsCategoryDto, ChartsCategory>(chartsCategory);
        if (category.Id == 0)
        {
            category = _context.ChartsCategories.Add(category).Entity;
            await _context.SaveChangesAsync();
            return CreatedAtAction("GetChartsCategory", new { id = category.Id }, _mapper.Map<ChartsCategory, ChartsCategoryDto>(category));
        }
        else
        {
            _context.ChartsCategories.Update(category);
            await _context.SaveChangesAsync();
            return NoContent();
        }
    }
    catch (Exception)
    {
        return StatusCode(StatusCodes.Status500InternalServerError, "Error updating data");
    }
}

Which is supposed to handle both create and update of the entity named ChartsCategory, which has a collection of Charts:

public partial class ChartsCategory
{
    public ChartsCategory()
    {
        Charts = new HashSet<Chart>();
        InverseParent = new HashSet<ChartsCategory>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string Label { get; set; }
    public string Icon { get; set; }
    public int? ParentId { get; set; }

    public virtual ChartsCategory Parent { get; set; }
    public virtual ICollection<Chart> Charts { get; set; }
    public virtual ICollection<ChartsCategory> InverseParent { get; set; }
}
  1. When I create a new entity - everything works as expected.
  2. When I update an existing entity - everything works as expected.
  3. Updating or creating a singular Chart within a ChartCategory - as expected.
  4. Deleting a Chart within the ChartsCategory doesn't work.

I would expect the Update() functionality to remove missing items. I found this answer however it seems a little too explicit. I want to globally state that a descendant item must be sent, otherwise it should be removed.

Thanks

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
noamyg
  • 2,747
  • 1
  • 23
  • 44
  • 1
    from this https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbset-1.update?view=efcore-5.0 you see that the `Update` method is not that magic, it can handle the `Modified` and `Added` states only, no `Deleted` or auto-setting optional FKs to null are handled. You must decide that logic by your own. The most natural way is include the collection navigation with the parent entity and delete each of them to make the tracking work properly. But that may not be suitable when the collection is large. At best you may even have to use raw script for performance reason. – King King Feb 10 '21 at 21:01

1 Answers1

0

I think that in the first case the retrieved user is not tracked by the context.


 _context.ChartsCategories.AsNoTrcking.Remove(category);

Pritom Sarkar
  • 2,154
  • 3
  • 11
  • 26