I have the following method, which receives an entity which was mapped from a dto. Therefor it is not tracked yet.
public async Task UpdateAsync(Entity value, CancellationToken cancellationToken)
{
dbContext.Update(value);
await dbContext.SaveChangesAsync(cancellationToken);
}
public class Entity
{
public Guid Id { get; set; }
public ICollection<Item> Items { get; set; }
}
public class Item
{
public Guid Id { get; set; }
public Guid EntityId { get; set; }
}
The Entity has a property Items which is a one to many relation. What is the best way to update the Entity and remove existing or add new relations? Currently it does not remove existing Items, which are not part of the collection anymore. I guess this is because, not all items are tracked, since the Entity is created from a dto. It seems like I have to load the existing Entity and all relations from the database first, and then manually map all the properties and relations (Add, Remove). This means a lot of work. Is there a better way to achieve this? Can EF somehow remove untracked relations?
CodePudding user response:
No, actually you need to separate add/update or delete logic. It is also better way to maintain you code later. Maybe you can try such approach (_factory is IServiceScopeFactory):
public async Task<TModel> UpdateAsync(TModel model)
{
using var scope = _factory.CreateScope();
await using var context = scope.ServiceProvider.GetRequiredService<ApplicationContext>();
var entry = await context.Set<TModel>().FirstAsync(t => t.Id == model.Id); // try other methods
var entryEntry = context.Entry(entry);
entryEntry.CurrentValues.SetValues(model);
await context.SaveChangesAsync();
return entryEntry.Entity;
}