C# 在实体框架中分离和附着对象时出错

C# 在实体框架中分离和附着对象时出错,c#,asp.net-mvc,ef-code-first,entity-framework-4.1,C#,Asp.net Mvc,Ef Code First,Entity Framework 4.1,我使用NoTracking获取对象,对其进行转换和操作,并将其发送到asp.net mvc视图。我返回一个已编辑的版本,调用我的存储库中的edit方法,尝试附加它,它会抛出以下错误: ObjectStateManager中已存在具有相同键的对象。ObjectStateManager无法使用同一密钥跟踪多个对象。 如何获取数据: IQueryable<User> query = db.Users.AsNoTracking(); public User UpdateUser(U

我使用NoTracking获取对象,对其进行转换和操作,并将其发送到asp.net mvc视图。我返回一个已编辑的版本,调用我的存储库中的edit方法,尝试附加它,它会抛出以下错误:

ObjectStateManager中已存在具有相同键的对象。ObjectStateManager无法使用同一密钥跟踪多个对象。

如何获取数据:

IQueryable<User> query = db.Users.AsNoTracking();
    public User UpdateUser(User user, IEnumerable<Expression<Func<User, object>>> properties)
    {
            db.Users.Attach(user); //Error happens right here.
            foreach (var selector in properties)
            {
                string propertyName = Helpers.PropertyToString(selector.Body);
                db.Entry(user).Property(propertyName).IsModified = true;
            }
            db.SaveChanges();
            return user;
    }

听起来您的db上下文只创建了一次,而该实例实际上是一个单例。当您尝试附加
用户
时,上下文检测到缓存中已经有一个用户,并且失败

我建议更改每个请求要创建的上下文。使用Ninject,您可以使用

Bind<YourDbContext>().ToMethod(context => CreateContext()).InRequestScope();

这将为每个请求创建一个新的DbCOntext,并防止缓存的
用户在附加时与提交的
用户发生冲突。

您的用户对象是否有子对象的集合?我最近遇到了一个问题,即附加父对象和两个新的子对象导致了此错误。子项都有空ID字段,因此“同一个键”错误不是我发送给
UpdateUser
方法的错误。模型有子项是,但这些子项已经在数据库中。确定。数据库上下文是否存储在会话或应用程序中?还是在每个请求上都创建一个新实例?我在global.ascx文件中创建了它。我使用DI在ninject模块内的每个存储库中注入上下文。因此,我不确定它是否适用于整个应用程序,或者它会根据每个请求创建一个应用程序。Ed,你能帮助我如何设置绑定吗。我不知道如何使用你的绑定。我编辑了我的问题和我如何做我的绑定。
Bind<YourDbContext>().ToMethod(context => CreateContext()).InRequestScope();
// DbContext db = new DbContext("ConnStringName");
Bind<DbContext>().ToMethod(context => new DbContext("ConnStringName")).InRequestScope();
Bind<IUserRepository>().To<SqlServerUserRepository>().InRequestScope();