使用EntityFramework 4.0进行批量插入会导致事务中止

Har*_*ryK 1 entity-framework transactions

我们通过WCF从客户端(Silverlight)接收文件,在服务器端我解析此文件.文件中的每一行都转换为一个对象并存储到数据库中.如果文件非常大(10000个条目和更多),我收到以下错误(MSSQLEXPRESS):

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

我尝试了很多(TransactionOptions超时设置等),但没有用.上面的异常消息是在3000之后引发的,有时是在处理了6000个对象之后引发的,但是我无法成功处理所有对象.

我追加了我的来源,希望有人有个主意,可以帮助我:

public xxxResponse SendLogFile (xxxRequest request
{
   const int INTERMEDIATE_SAVE = 100;



   using (var context = new EntityFramework.Models.Cubes_ServicesEntities())
   {
            // start a new transactionscope with the timeout of 0 (unlimited time for developing purposes)
            using (var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew,
            new TransactionOptions
            {
                IsolationLevel = System.Transactions.IsolationLevel.Serializable,
                Timeout = TimeSpan.FromSeconds(0)
            }))
            {
                try
                {
                    // open the connection manually to prevent undesired close of DB
                    // (MSDTC)
                    context.Connection.Open();
                    int timeout = context.Connection.ConnectionTimeout;

                    int Counter = 0;

                    // read the file submitted from client
                    using (var reader = new StreamReader(new MemoryStream(request.LogFile)))
                    {
                        try
                        {
                            while (!reader.EndOfStream)
                            {
                                Counter++;
                                Counter2++;
                                string line = reader.ReadLine();
                                if (String.IsNullOrEmpty(line)) continue;

                                // Create a new object
                                DomainModel.LogEntry le = CreateLogEntryObject(line);

                                // an attach it to the context, set its state to added.
                                context.AttachTo("LogEntry", le);
                                context.ObjectStateManager.ChangeObjectState(le, EntityState.Added);

                                // while not 100 objects were attached, go on
                                if (Counter != INTERMEDIATE_SAVE) continue;

                                // after 100 objects, make a call to SaveChanges.
                                context.SaveChanges(SaveOptions.None);
                                Counter = 0;
                            }
                        }
                        catch (Exception exception)
                        {
                            // cleanup
                            reader.Close();
                            transactionScope.Dispose();
                            throw exception;

                        }

                    }
                    // do a final SaveChanges
                    context.SaveChanges();
                    transactionScope.Complete();
                    context.Connection.Close();
                }
                catch (Exception e)
                {
                    // cleanup
                    transactionScope.Dispose();
                    context.Connection.Close();
                    throw e;
                }
            }

            var response = CreateSuccessResponse<ServiceSendLogEntryFileResponse>("SendLogEntryFile successful!");
            return response;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Lad*_*nka 7

没有批量插入的实体框架.您SaveChanges在100条记录之后调用,但它将执行100个单独的插入,每个插入数据库往返.

设置事务超时还取决于在机器级别配置的事务最大超时(我认为默认值为10分钟).在手术失败之前需要多长时间?

您可以做的最好的方法是使用通用ADO.NET或批量插入重写插入逻辑.

顺便说一句.throw exceptionthrow e?这是重新抛出异常的错误方法.

重要编辑:

SaveChanges(SaveOptions.None)!表示保存后不接受更改,因此所有记录仍处于添加状态.因为第一次调用SaveChanges将插入前100条记录.第二个调用将再次插入100个+下一个100,第三个调用将插入第一个200 +下一个100,等等.