,导致尝试创建现有实体的新副本我正在尝试创建具有特定角色的新用户对象。“角色”是EF中的现有实体。我用谷歌搜索和堆栈溢出,直到我脸色发青,我已经尝试了所有似乎对其他人都有效的方法。但是当我尝试保存我的新用户对象时,它首先尝试创建一个新的“角色”,而不是仅仅通过引用现有角色来创建一个新的用户对象。我究竟做错了什么?角色myRole=新角色{ID=myUser.Role.ID};myObjectContext.Roles.Attach(myRole);我的用户角色=我的角色;如果(myUser.ID==0){myObjectContext.Users.AddObject(myUser);}else{if(myUser.EntityState==System.Data.EntityState.Detached){myObjectContext.Users.Attach(myUser);}myObjectContext.ObjectStateManager.ChangeObjectState(myUser,System.Data.EntityState.Modified);}myObjectContext.SaveChanges(SaveOptions.None);编辑-经过更多测试......好吧......所以我还是找到了“原因”的一部分。我仍然不知道为什么会这样,需要帮助。基本上,我有两组数据附加到我的新用户对象。一个是“角色”,它是包含角色的角色表的FK。这显示为用户的导航属性,例如“User.Role”。第二组数据是称为“FIPS”的对象集合,它们是用户与另一个称为FIPS的表之间的多对多关系。它们之间有一个关系表,它只包含两列,每一列分别是User和FIPS的外键。用户的FIPS也是一个参考属性,像“User.FIPS”一样被引用。下面是完整的代码,显示了在保存上下文之前将FIPS和角色分配给用户对象。列表fipsList=newList();foreach(FIPSfipsinmyUser.FIPS){fipsList.Add(fips.FIPS_Code);}myUser.FIPS.Clear();foreach(fipsList中的字符串fipsCode){FIPSmyFIPS=newFIPS{FIPS_Code=fipsCode};myObjectContext.FIPSCodes.Attach(myFIPS);我的用户.FIPS.添加(myFIPS);}角色myRole=新角色{ID=myUser.Role.ID};myObjectContext.Roles.Attach(myRole);我的用户。角色=我的角色;如果(myUser.ID==0){myObjectContext.Users.AddObject(myUser);}else{if(myUser.EntityState==System.Data.EntityState.Detached){myObjectContext.Users.Attach(myUser);}myObjectContext.ObjectStateManager.ChangeObjectState(myUser,System.Data.EntityState.Modified);}myObjectContext.SaveChanges(SaveOptions.None);我将我的手表设置为检查"myObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added)"的状态,以查看何时向其添加内容。一旦第一个Related对象添加到User对象,第二个尚未附加到上下文的Related对象就被添加到EntityState为“Added”的上下文中。....看看是否有办法避免将相关实体附加到用户实体,直到它们都附加到上下文。--FOLLOWUP--好的..我改变了代码的顺序,以便相关实体在分配给用户实体之前附加到上下文..但是一旦第一个相关实体被分配,第二个相关实体就会出现在ObjectStateEntries中作为“添加”。因此,然后我将其更改为以下顺序:将所有相关实体附加到上下文。删除用户对象与相关实体类型的现有关系。将相关实体分配给用户实体。保存用户实体。而且......现在......它有效......它有效......!=)自从我编写下面的代码以来已经有一段时间了,但我依稀记得遇到了同样的问题并且它正在发生,因为正在添加的角色当前正在被上下文跟踪,所以追加存根添加了新角色Id与同样的效果。在下面的代码中,我首先检查ChangeTracker并在跟踪角色时使用现有条目。//添加在dto.Roles中但不在resource.Roles中的角色//使用更改跟踪器条目,或添加存根角色varrolesToAdd=fromDto.Roles.Where(r=>!toResource.Roles.Any(role=>role.Id==r)).ToList();varroleEntries=dbContext.ChangeTracker.Entries();foreach(varidinrolesToAdd){varrole=roleEntries.Where(e=>e.Entity.Id==id).Select(e=>e.Entity).FirstOrDefault();if(role==null){role=newRole{Id=id};dbContext.Set().Attach(角色);}到资源。角色。添加(角色);如果您的Role实体已经存在于数据库中,为什么要创建它的新实例?无论如何,如果您手动将新实例附加到上下文,如果附加实例的ID存在于数据库中,它应该可以工作。但是在您的情况下,以下几行有点奇怪:RolemyRole=newRole{ID=myUser.Role.ID};myObjectContext.Roles.Attach(myRole);我的用户角色=我的角色;具有Role实例(myUser.Role)ID的新角色,然后附加新实例,最后再次影响您的实例。这里一定有问题。如果您的角色已经存在(我假设第一行写入myUser.Role.ID时似乎就是这种情况),您为什么要创建一个新实例。扔掉这3行。从数据库中获取您的角色。然后影响从数据库到myUser.Role属性的Role。这就是我在我的案例中所做的。这是一个类似的情况,其中Item包含ICollection,其中没有更新并且需要在项目上添加现有属性。首先,我遍历了项目的每个属性。我不得不将它从本地context.Set().Local.Where(x=>x.Id==attr.Id).ToList().ForEach(p=>context.Entry(p).State=EntityState.分离);然后我附上。context.Set().Attach(attr);然后我将数据重新加载到它。context.Entry(attr).Reload();尝试使用此代替前三行(如果用户对象已经知道其角色的ID并被丢弃,则根本不需要它们):与现有实体相关的新实体,导致尝试创建新副本现有实体的。如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——intid=myUser.Role.ID;//Role应该是NULL,如果用户实际上是新用户...//难道你想写myUser.RoleID?角色myRole=myObjectContext.Roles.FirstOrDefault(x=>x.ID==id);我的用户角色=我的角色;本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
