我对实体框架有一些奇怪的问题。我尝试更新与User
有多对多关系的实体Team
。当我尝试将一些团队(存在于数据库中)添加到用户时,数据库中没有任何变化。但是,当我从用户中删除所有团队时,它将持久存储到数据库,并且用户没有任何团队。为什么添加不持久?有什么想法吗?
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();
}
}
答案 0 :(得分:1)
问题是,当您调用context.Entry(entity).State = EntityState.Modified;
时,引用的Team
条目将设置为State = EntityState.Unchanged
,该集合将不会被识别为已修改,EF将忽略该尝试通过context.Entry(entity).Collection(u => u.Teams).Load();
获取实际数据库值,它也无法通过clear和re-add识别更改,因为context.Teams.Find(teamId)
将返回已标记为未更改的本地条目,并且末尾的集合将包含与最初的数据相同。
可能的解决方案:在设置State Modified之前清除集合,然后从数据库加载集合并在重新添加项目之前再次清除:
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();
}
请看这里有一个类似的主题:Updating a reference to a child object in Entity framework 4.1 (CodeFirst)即使它只是一个参考而不是一个集合,基本问题是相同的。
有关Collection(..).Load()
的文档的引用:
从数据库中加载实体集合。注意实体那个 已存在于上下文中的数据不会被数据库中的值覆盖。
这是为什么在最初填充集合时,加载对于获取实际数据库状态无效的原因之一。