【发布时间】:2017-08-10 18:55:04
【问题描述】:
我正在关注Fastest Way of Inserting in Entity Framework的代码
我在运行此代码时收到此错误消息,但我不知道我做错了什么,因为我完全从页面上复制了它。关于我做错了什么有什么想法吗?
错误信息:与当前连接关联的事务已完成但尚未处理。必须先释放事务,然后才能使用连接执行 SQL 语句。
代码似乎运行了一段时间,但它几乎同时在我在下面标记的行处停止。我不确定发生了什么。
堆栈跟踪:
在 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,布尔 startLocalTransaction) 在 System.Data.Entity.Core.Objects.ObjectContext.c__DisplayClass2a.b__27() 在 System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 操作) 在 System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions 选项,布尔型 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;
}
【问题讨论】:
-
请发布完整的异常堆栈。
-
您引用的答案可以追溯到 6 年前。我确信从那以后发生了很多变化。你到底想做什么?您设置代码的方式是将交易包装在交易中。
-
@Juan 我有超过一百万行要插入数据库,所以我试图找到一种快速的方法来完成它。我还发布了完整的异常堆栈
-
您现在已经意识到,EF 并不是专门为批量操作而构建的。您是否关心数据是否以块的形式提交?或者您是否需要同时提交数百万条记录?
-
@Juan 我不在乎它是否分块提交,只要它快速完成即可
标签: c# sql multithreading entity-framework linq