Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 保存到数据库时出现InvalidOperationException_C#_Database_Linq_Entity Framework - Fatal编程技术网

C# 保存到数据库时出现InvalidOperationException

C# 保存到数据库时出现InvalidOperationException,c#,database,linq,entity-framework,C#,Database,Linq,Entity Framework,我在向数据库添加帖子时遇到问题,这个“Add”函数是从多个线程调用的。通常很快,我不知道这是否重要,但这就是它的工作方式 代码: 我的问题是,当调用SaveChanges时,会出现以下异常: 已成功提交对数据库的更改,但 更新对象上下文时出错。这个 ObjectContext可能处于不一致的状态。内部异常 消息:AcceptChanges无法继续,因为对象的键 值与ObjectStateManager中的另一个对象冲突。制作 在调用AcceptChanges之前,请确保键值是唯一的 我找到的所有

我在向数据库添加帖子时遇到问题,这个“Add”函数是从多个线程调用的。通常很快,我不知道这是否重要,但这就是它的工作方式

代码:

我的问题是,当调用SaveChanges时,会出现以下异常:

已成功提交对数据库的更改,但 更新对象上下文时出错。这个 ObjectContext可能处于不一致的状态。内部异常 消息:AcceptChanges无法继续,因为对象的键 值与ObjectStateManager中的另一个对象冲突。制作 在调用AcceptChanges之前,请确保键值是唯一的

我找到的所有答案都与您必须添加的内容有关,我已经做好了准备,但没有任何帮助

<Property Name="ID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />


那么有没有其他办法解决这个问题呢

归根结底,在线程之间共享对象上下文是一个非常糟糕的主意。对象上下文旨在用作工作单元,即短期的;典型用法:

using(var ctx = new SomeObjectContextType()) // assuming IDisposable
{
    // not shown: get some records, if needed
    ...
    // not shown: update, add, remove some records, if needed

    ctx.SaveChanges();
} // and now it is gone, never to be used again
它可能比某些场景中的情况要复杂一些,例如在页面/请求期间保留对象上下文,但不应在调用方之间共享。原因很多,但基本上所有竞争更新都需要锁定,这里的“更新”包括从数据库读取任何记录或延迟加载属性的简单操作。当被多个线程访问时,对象上下文会变得不稳定,这并不奇怪:这种情况(通常)不受支持

此外,具有长期对象上下文还存在其他问题:

  • 有时情况会变糟(例如超时、死锁、回滚,或者只是一个简单的连接错误);在这里,适当的响应方式就是丢弃现在已损坏的对象上下文(
    Dispose()
    it,如果合适的话)-并忘掉它;如果要重新应用更改,请从新的对象上下文开始
  • 对象上下文包括身份映射和变更管理系统;如果你将它保存的时间超过一次操作,你会慢慢地将越来越多的物体积累到其中;除了造成内存问题外,这还会逐渐降低性能,因为现在每一次读取/更新操作都需要处理越来越多的数据

基本上,这里的“修正”是:不要这样做。这不是对象上下文的正确用法。没有应用程序范围的共享对象上下文。

不一致始终表示进程尚未完全终止ist工作。如果使用多个线程访问数据库,则DBMS必须能够处理此问题,或者必须使代码具有线程安全性。使用多个线程的对象上下文通常意味着发生了非常糟糕的事情—这不是预期的用法,可能会导致非常糟糕的事情。接受异常也是一个非常糟糕的主意。你能详细介绍一下这里的情况吗?这是什么类型的应用程序,为什么它在线程之间共享对象上下文?谢谢!这看起来很有效,如果我这样做,我甚至可以跳过我的锁吗?@Nick3-yes;如果没有共享对象上下文,则没有理由进行同步
using(var ctx = new SomeObjectContextType()) // assuming IDisposable
{
    // not shown: get some records, if needed
    ...
    // not shown: update, add, remove some records, if needed

    ctx.SaveChanges();
} // and now it is gone, never to be used again