Reputation: 145
I have strange problem with entity framework. I'm trying to update my entity User
which has many-to-many relation with Team
. When I try to add some team (which exists in database) to the user nothing changes in the database. However when I remove all teams from the user it is persiting to database and the user is free of any team. Why adding is not persisting? Any ideas?
public int Save(User entity)
{
using (var context = new UsersContext())
{
var teamIds = entity.Teams.Select(t => t.Id).ToArray();
context.Entry(entity).State = EntityState.Modified;
context.Entry(entity).Collection(u => u.Teams).Load();
entity.Teams.Clear();
foreach (var teamId in teamIds)
{
entity.Teams.Add(context.Teams.Find(teamId));
}
return context.SaveChanges();
}
}
Upvotes: 2
Views: 72
Reputation: 13438
The problem is, the moment you call context.Entry(entity).State = EntityState.Modified;
, the referenced Team
entries will be set to State = EntityState.Unchanged
, the collection will not be recognized as modified, EF will ignore the attempt to get the actual database values via context.Entry(entity).Collection(u => u.Teams).Load();
and it will also not recognize the changes with clear and re-add, because context.Teams.Find(teamId)
will return the local entries that where already marked unchanged and the collection at the end will contain the same data as it did initially.
Possible Solution: clear collection before setting State Modified, then load the collection from database and clear again before re-adding your items:
using (var context = new DbC())
{
var teamIds = entity.Teams.Select(t => t.Id).ToArray();
entity.Teams.Clear();
context.Entry(entity).State = EntityState.Modified;
context.Entry(entity).Collection(u => u.Teams).Load();
entity.Teams.Clear();
foreach (var teamId in teamIds)
{
entity.Teams.Add(context.Teams.Find(teamId));
}
return context.SaveChanges();
}
See here for a somewhat similar topic: Updating a reference to a child object in Entity framework 4.1 (CodeFirst) even though it is about a single reference rather than a collection, the basic problem is the same.
A quote from documentation regarding the Collection(..).Load()
:
Loads the collection of entities from the database. Note that entities that already exist in the context are not overwritten with values from the database.
This is part of why loading is not effective to get the actual database state, when the collection is initially filled.
Upvotes: 1