简体   繁体   中英

Update many-to-many relations in Entity Framework

Situation: I have something like a tags: user can change list of tags for some entity. Entity and tag has-many-to many relation.

Problem : user can add some new tags, remove some old tags and keep some tags without changing. For example:

  • Before: a, b, c
  • After: b, c, d

Tag a was deleted, tag d was added. What is most efficient way to do this with minimizing number of SQL queries?

Possible solutions :

I found two solutions, but I don't think they are good

  1. Delete all old tags and add new

     // entityId - editing entity's id // tagIds - new tags ids var entity _entityRepository.GetAll() .Include(x => x.Tags) .FirstOrDefault(x => x.Id == entityId); entity.Tags.RemoveAll(); // Add new tags entity.Tags = _tagsRepository.GetAll() .Where(x => tagIds.Contains(x.Id)); //Yes, this .Contains works _entityRepository.Update(entity); 
  2. Compare old list of tags with new list of tags and add or remove to make them equivalent.

     // entityId - editing entity's id // tagIds - new tags ids var entity _entityRepository.GetAll() .Include(x => x.Tags) .FirstOrDefault(x => x.Id == entityId); // Add tags which not exists in entity.Tag foreach (var tagId in tagIds) { if (!entity.Tags.Any(x => x.Id == tagId)) { //A lot of queiries! var newTag = _tagsRepository.GetAll() .FirstOrDefault(x => x.Id == tagId); entity.Tags.Add(newTag); } } // Remove tags whic not exists in tagIds // Assuming Tags is IList<T> and we can use [] int i = 0; while (i < entity.Tags.Count) { if (!tagIds.Contains(entity.Tags[i].Id)) entity.Tags.RemoveAt(i); else i++; } _entityRepository.Update(entity); 

Solutions pros and cons

First solution pros:

  • Few SQL queries

First solution cons:

  • Remove all relations and create new, no matter did they change
  • Load all Tags using Include

Second solution pros:

  • No remove all

Second solution cons:

  • A lot of queries for loading every new Tag
  • Load all Tags using Include

What is the best solution for this problem?

Don't compare anything, don't implement 'logic' which checks which flags were removed and which added.

Instead, just assign a new list of tags to your entity and tell Entity Framework to save the object. It will figure out on its own which ones have to be removed and which ones to be added.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM