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



我得到对象,使用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);

听起来你的数据库上下文是创建一次,该实例是有效的单例。当您尝试附加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冲突。

相关内容

  • 没有找到相关文章

最新更新