An entity object cannot be referenced by multiple instances of IEntityChangeTracker
中文是:
问题现象:
一个角色表,一个用户表,用户表中的RoleId引用角色表中的RoleId。对用户表添加记录时,出现上述问题。
程序采用三成架构,级数据访问层、业务逻辑层,在业务逻辑层负责新增操作。
新增数据的代码如下:
表示层:
dmUser user=new User{UserId="test",UserName="test"}; //dmUser是表dmUser在实体模型中的映射
user.dmRoleReference.Value=RoleManager.GetRoleById(roleId); //添加User表的关联对象
UserManager.Add(user); //调用UserManager中的Add方法向数据库添加记录
UserManager.Add方法中的主要代码:
using(Entities db=new Entitles) //Entities,数据库的实体模型
{
db.AddToUser(user); //这里出现本文所说的错误
db.SaveChanges();
}
百思不得其解,反复上网搜索,没有找到答案,虽然找到一篇博文说解决了这个问题,但其所用的方法实在不敢恭维,应该会对程序造成很大的负面影响,而且他那个方法也不能适用到我的代码中。
“对象服务使用 IEntityChangeTracker 的实例来跟踪对附加到 ObjectContext 的对象的更改。对于每个被跟踪对象,都有一个 IEntityChangeTracker 实例。”微软的某一篇文档中有这样一句话,给了我一点提示。
经过多次编写代码验证,终于明白,使用EF更新数据时,如果要更新的对象有相关的对象(换句话说,就是要更新的表有主外键关系),这些对象必须来自同一个IEntityChangeTracker 。
而我的问题就出在user.dmRoleReference.Value=RoleManager.GetRoleById(roleId); 这里,在RoleManager.GetRoleById(roleId)方法中的实体对象和UserManager.Add方法中使用的实体对象不是同一个对象,也就产生了不同的IEntityChangeTracker 实例,因此出现本文所说的错误。
对UserManager.Add方法做如下修改即可
using(Entities db=new Entitles) //Entities,数据库的实体模型
{
user.dmRoleReference.Value=db.dmRole.First(r=>r.RoleId==roleId);
db.AddToUser(user);
db.SaveChanges();
}