在实体框架中分离和附加对象时出错

时间:2011-04-21 02:29:51

标签: c# asp.net-mvc ef-code-first entity-framework-4.1

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

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

我如何获取数据:

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

当我使用AsNoTracking获取实体时,不应该为我分离这些内容吗?即使它没有分离,整个asp.net生命周期也应该在重新提交数据时重新启动,这会使图表变空。

我在这里做错了什么?

我做这样的绑定:

DbContext db = new DbContext("ConnStringName");
Bind<IUserRepository>().To<SqlServerUserRepository>()
                .WithConstructorArgument("db", db);

1 个答案:

答案 0 :(得分:1)

听起来您的数据库上下文是一次创建的,并且该实例实际上是一个单例。当您尝试附加User时,上下文检测到它已经在缓存中有一个并且失败。

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

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

其中YourDbContextdb变量的类型,而CreateContext()是global.ascx中的方法。

<强>更新

您确实创建了一次数据库上下文并将其存储为单例。不用担心,您可以将绑定设置为

// DbContext db = new DbContext("ConnStringName");
Bind<DbContext>().ToMethod(context => new DbContext("ConnStringName")).InRequestScope();
Bind<IUserRepository>().To<SqlServerUserRepository>().InRequestScope();

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