与当前连接关联的事务已完成但尚未处理

时间:2017-08-10 18:55:05

标签: c# sql multithreading entity-framework linq

我正在关注Fastest Way of Inserting in Entity Framework

上的代码

我运行此代码时收到此错误消息,因为我完全从页面复制了该错误,因此我无法说出我做错了什么。关于我做错什么的任何想法?

错误消息:与当前连接关联的事务已完成但尚未处理。必须先处理事务,然后才能使用连接执行SQL语句。

代码似乎运行了一段时间但是它几乎会在我下面标记的行的同时停止。我不确定发生了什么。

堆栈跟踪:

  

at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()   在System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.b__2(UpdateTranslator ut)   在System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update [T](T noChangesResult,Func`2 updateFunction)   在System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()   在System.Data.Entity.Core.Objects.ObjectContext.b__35()   在System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction [T](Func`1 func,IDbExecutionStrategy executionStrategy,Boolean startLocalTransaction,Boolean releaseConnectionOnSuccess)   在System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions选项,IDbExecutionStrategy executionStrategy,Boolean startLocalTransaction)   在System.Data.Entity.Core.Objects.ObjectContext。<> c__DisplayClass2a.b__27()   在System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute [TResult](Func`1操作)   at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options,Boolean executeInExistingTransaction)   在System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions选项)   在System.Data.Entity.Internal.InternalContext.SaveChanges()

public static async Task startInitialMarketSymbolsDownload(string market)
        {
            try
            {
                List<string> symbolList = new List<string>();
                symbolList = getStockSymbols(market);

                var historicalGroups = symbolList.Select((x, i) => new { x, i })
                          .GroupBy(x => x.i / 50)
                          .Select(g => g.Select(x => x.x).ToArray());

                List<DailyAmexData>[] amexListArray = await Task.WhenAll(historicalGroups.Select(g => Task.Run(() => getLocalHistoricalStockData(g, market))));


                using (TransactionScope scope = new TransactionScope())
                {
                    ooplesfinanceEntities context = null;
                    List<DailyAmexData> amexList = null;

                    try
                    {
                        amexList = new List<DailyAmexData>();

                        foreach (List<DailyAmexData> singleList in amexListArray)
                        {
                            amexList.AddRange(singleList);
                        }

                        context = new financeEntities();
                        context.Configuration.AutoDetectChangesEnabled = false;

                        int count = 0;
                        foreach (var amexData in amexList)
                        {
                            ++count;
                            context = AddToContext(context, amexData, count, 100, true);
                        }

                        context.SaveChanges();
                        Console.WriteLine("Everything is finished!");
                    }
                    finally
                    {
                        if (context != null)
                            context.Dispose();
                    }

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.InnerException.Message);
            }
        }

        private static financeEntities AddToContext(financeEntities context, DailyAmexData entity, int count, int commitCount, bool recreateContext)
        {
            context.Set<DailyAmexData>().Add(entity);

            if (count % commitCount == 0)
            {
                context.SaveChanges(); **// seems to happen at this line**
                Console.WriteLine("100 items saved");
                if (recreateContext)
                {
                    context.Dispose();
                    context = new financeEntities();
                    context.Configuration.AutoDetectChangesEnabled = false;
                }
            }

            return context;
        }

1 个答案:

答案 0 :(得分:1)

如果您需要插入一百万行,那么您应该使用批量插入。我写了一个通用的批量插入类,我在这里发布了代码。

Bulk Insert of Generic List C# into SQL Server

我希望它有所帮助。