Reputation: 1566
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:
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
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);
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:
First solution cons:
Tags
using Include
Second solution pros:
Second solution cons:
Tags
using Include
What is the best solution for this problem?
Upvotes: 1
Views: 78
Reputation: 4130
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.
Upvotes: 2