'EF Core 5.0 Many-To-Many delete from nested collection
My models are like this (simplified):
public class Request
{
public string Id { get; set; }
public List<Tag> Tags { get; set; }
}
public class Tag
{
public string Id { get; set; }
public List<Request> Requests { get; set; }
}
DatabaseContext (as shown in documentation here: Many-To-Many):
builder.Entity<Request>()
.HasMany(r => r.Tags)
.WithMany(f => f.Requests)
.UsingEntity(j => j.ToTable("request_tags"));
How do I delete element from Request.Tags collection without deleteting tag itself? Basically I need to delete entry in join table. I tried in controller something like this:
[HttpGet("[action]")]
public async Task<IActionResult> DeleteTag(string requestId, string tagId)
{
var request = await _context.Requests
.Include(r => r.Tags)
.SingleOrDefaultAsync(r => r.Id.Equals(requestId));
var itemToDelete = request.Tags.SingleOrDefault(f => f.Id.Equals(tagId));
request.Tags.Remove(itemToDelete);
_context.Requests.Update(request); //AsNoTracking behaviour is enabled
await _context.SaveChangesAsync();
return Ok();
}
And it takes no effect. I can manually delete row on join table via _context.Database.ExecuteSqlRaw() but it seems like workaround. Is there a better way?
Solution 1:[1]
Here is how I think about it, I assume it is because EF requires you to be expressive by default, so you don't hurt yourself. Your code called Update()
, which means you want to update a record, not do any deletes. It wants you to call Remove() on the record set itself.
As is change your Remove call to:
_context.Tags.Remove(itemToDelete);
Update: Just saw this here, it might be what you are looking for, read that link, I've never tried it though:
.OnDelete(DeleteBehavior.ClientCascade);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |