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);