实体框架新的交易是不允许的,因为在会话中运行其他线程,多线程保存(Entity Framework

2019-08-17 12:32发布

我tryng到一个数据库保存了多线程processo的日志,但我发现了以下错误:新的事务是不允许的,因为在会话中运行其他线程。

在每个胎面我有这样的功能:

 internal bool WriteTrace(IResult result, string message, byte type)
    {
        SPC_SENDING_TRACE trace = new SPC_SENDING_TRACE(
                        message,
                        Parent.currentLine.CD_LINE,
                        type,
                        Parent.currentUser.FULLNAME,
                        Parent.guid);
        Context.SPC_SENDING_TRACE.AddObject(trace);
        if (Context.SaveChanges(result) == false)
            return false;
        return true;

    }

上下文是每个线程不同,但与数据库的连接始终是相同的。

有没有解决这个问题的方法吗?

谢谢安德烈

Answer 1:

你应该为每个事务上下文,然后处理它,你可以是这样做的:

using(var ctx = new MyContext()) {
    //do transaction here
}

闭合支架后的上下文被设置。

为了更好地理解参考这篇文章 ,你可以找到一个伟大的答案ken2k 。 希望你能解决您发出:)

更新:

你也应该尝试加入.ToList()的每一个LINQ查询你有。 当我们通过遍历LINQ结果,直到迭代结束,你不能做任何修改。 检查您是否有类似的东西,或分享更多的代码,即在一段代码,你叫WriteTrace 。 希望这一次这实际上可以帮助你。



Answer 2:

我使用实体框架在多线程环境下,任何线程,用户界面和后台(STA和MTA),可以同时更新相同的数据库。 我通过重新从头开始创建,在使用开始任何新的后台线程实体连接解决了这个问题。 检查实体连接实例的ConnectionString显示了读者的GUID我以为是用来连接公共连接实例。 通过从头开始重新创建实体连接的GUID值是为每个线程不同,没有出现冲突发生。

// Build the connection string.

  var sqlBuilder = new SqlConnectionStringBuilder();
  sqlBuilder.DataSource = serverName;
  sqlBuilder.InitialCatalog = databaseName;
  sqlBuilder.MultipleActiveResultSets = true;
  ...
  var providerString = sqlBuilder.ToString();
  var sqlConnection = new SqlConnection(providerString);

// Build the emtity connection.

  Assembly metadataAssembly = Assembly.GetExecutingAssembly();
  Assembly[] metadataAssemblies = { metadataAssembly };
  var metadataBase = @"res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl";
  var dbModelMetadata = String.Format(metadataBase, objectContextTypeModelName);
  // eg: "res://*/Models.MyDatabaseModel.csdl|res://*/Models.MyDatabaseModel.ssdl|res://*/Models.MyDatabaseModel.msl"
  var modelMetadataPaths = modelMetadata.Split('|');
  var metadataWorkspace = new MetadataWorkspace(modelMetadataPaths, metadataAssemblies);
  var entityDbConnection = new EntityConnection(metadataWorkspace, sqlConnection);
  return entityDbConnection;


文章来源: Entity Framework new transaction is not allowed because there are other threads running in the session, multi thread save