C# foreach循环实体框架中的附加上的ObjectStateManager错误
因此,我有一个(新)用户表和一个组表。我要做的是将用户添加到组中 我想我应该做的是:-C# foreach循环实体框架中的附加上的ObjectStateManager错误,c#,entity-framework,C#,Entity Framework,因此,我有一个(新)用户表和一个组表。我要做的是将用户添加到组中 我想我应该做的是:- using(context = new MyEntity()) { foreach(csvUser from csvSource) { User oUser = new User(); oUser.Firstname = csvUser.Firstname; Group oGroup = new Group(); // Set
using(context = new MyEntity())
{
foreach(csvUser from csvSource)
{
User oUser = new User();
oUser.Firstname = csvUser.Firstname;
Group oGroup = new Group();
// Set the primary key for attach
oGroup.ID = csvUser.GroupID;
context.Group.Attach(oGroup);
oUser.Groups.Add(oGroup);
context.Users.Add(oUser);
}
context.saveChnages();
}
因此,基本上循环所有新用户,从CSV文件中获取他们的组id(组已经存在于数据库中)。因此,我将附加到组,然后添加组
然而,我遇到了一个错误,因为一旦一个已经连接了组id的用户尝试连接它,它就会发出隆隆声
具有与所提供对象的键匹配的键的对象可能会失败
在ObjectStateManager中找不到。验证
提供的对象与要访问的对象的键值匹配
必须应用更改
我可以理解,它试图重新连接一个已经连接到内存中的对象。然而,有办法解决这个问题吗?我所需要做的就是将一个新用户附加到数据库中预先存在的组 用户和组之间似乎存在多对多关系。如果是这种情况,并且您首先使用代码,那么您的模型可以这样定义
public class User
{
public int Id { get; set; }
public string Firstname { get; set; }
// Other User properties...
public virtual ICollection<UserGroup> UserGroups { get; set; }
}
public class Group
{
public int Id { get; set; }
// Other Group properties...
public virtual ICollection<UserGroup> UserGroups { get; set; }
}
public class UserGroup
{
public int UserId { get; set; }
public User User { get; set; }
public int GroupId { get; set; }
public Group Group { get; set; }
}
现在你的任务更简单了
foreach (var csvUser in csvSource)
{
User oUser = new User();
oUser.Firstname = csvUser.Firstname;
// Find Group
var group = context.Groups.Find(csvUser.GroupID);
if(group == null)
{
// TODO: Handle case that group is null
}
else
{
// Group found, assign it to the new user
oUser.UserGroups.Add(new UserGroup { Group = group });
context.Users.Add(oUser);
}
}
context.SaveChanges();
似乎您正在为每个迭代的
用户添加一个新的组
,请尝试以下操作:
using(context = new MyEntity())
{
// fetch Groups and add them first
foreach(groupId in csvSource.Select(x => x.GroupID).Distinct())
{
context.Groups.Add(new Group { ID = groupId });
}
// add users
foreach(csvUser from csvSource)
{
User oUser = new User();
oUser.Firstname = csvUser.Firstname;
var existingGroup = context.Groups.Single(x => x.Id == csvUser.GroupID);
oUser.Groups.Add(existingGroup);
context.Users.Add(oUser);
}
context.saveChnages();
}
该错误通常与ApplyCurrentValues
以某种形式或形状关联-当它试图更新(以前)分离的实体时
现在还不完全清楚为什么在你的案例中会发生这种情况——但也许你有其他事情在发生——或者你只是把EF与重新加入同一个组“混淆”
我认为最简单的方法就是使用Find
-并避免Attach
context.Group.Find(csvUser.GroupID);
如果有缓存,则从缓存加载,如果需要,则从Db加载
如果上下文中存在具有给定主键值的实体,
然后,它会立即返回,而无需向商店提出请求。
否则,将向存储区请求具有给定属性的实体
主键值和该实体(如果找到)将附加到
上下文并返回。如果在上下文或
存储,则返回null
那会帮你解决问题的
我想,您也可以关闭从Db应用值(但目前我无法检查) 你为什么要附加它?通过“添加”,您已经“附加”了实体,并将其状态更改为“已添加”。此外,您正在为每个“用户”创建一个“组”,而这(据我所知)不是您想要的。你最好先添加你的“组”,然后添加带有“user.Group=Group”的用户。haim770-这些组已经存在,我只是尝试将它们关联起来。只有用户是新的。
using(context = new MyEntity())
{
// fetch Groups and add them first
foreach(groupId in csvSource.Select(x => x.GroupID).Distinct())
{
context.Groups.Add(new Group { ID = groupId });
}
// add users
foreach(csvUser from csvSource)
{
User oUser = new User();
oUser.Firstname = csvUser.Firstname;
var existingGroup = context.Groups.Single(x => x.Id == csvUser.GroupID);
oUser.Groups.Add(existingGroup);
context.Users.Add(oUser);
}
context.saveChnages();
}
context.Group.Find(csvUser.GroupID);