2017-05-17 1 views
0

아래 기능으로 데이터베이스를 업데이트하려고합니다. 하지만이 함수를 실행할 때마다 DataReader를 닫지 않았다고 명시했습니다. 오류 - 먼저 닫아야하는이 명령과 연결된 열려있는 DataReader가 이미 있습니다. 어디에 내가 문을 닫아야하는지 묻고 싶습니다. 고맙습니다. 원인이DataReader를 닫으려고합니다.

[InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.] 
    System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) +1543253 
    System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) +101 
    System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) +268 
    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +91 
    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +53 
    System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +161 
    System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +41 
    System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +12 
    System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c) +14 
    System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch(TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) +72 
    System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext) +402 
    System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior) +166 
    System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +12 
    System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +36 

[EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details.] 
    System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +103 
    System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute(ObjectContext context, ObjectParameterCollection parameterValues) +758 
    System.Data.Entity.Core.Objects.<>c__DisplayClass7.<GetResults>b__6() +90 
    System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction(Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) +288 
    System.Data.Entity.Core.Objects.<>c__DisplayClass7.<GetResults>b__5() +154 
    System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Func`1 operation) +190 
    System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +283 
    System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0() +15 
    System.Data.Entity.Internal.LazyEnumerator`1.MoveNext() +45 
    System.Linq.Enumerable.SingleOrDefault(IEnumerable`1 source) +121 
    System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__2(IEnumerable`1 sequence) +40 
    System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable`1 query, Expression queryRoot) +59 
    System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(Expression expression) +114 
    System.Data.Entity.Internal.Linq.DbQueryProvider.Execute(Expression expression) +116 
    System.Linq.Queryable.SingleOrDefault(IQueryable`1 source, Expression`1 predicate) +249 
    WITS_v4.Pages.updateRecord.updateICAT(DataSet s) in C:\Users\khongkok\Source\Repos\WITS\WITS v4\Pages\updateRecord.aspx.cs:94 
    WITS_v4.Pages.updateRecord.Page_Load(Object sender, EventArgs e) in C:\Users\khongkok\Source\Repos\WITS\WITS v4\Pages\updateRecord.aspx.cs:22 
    System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +51 
    System.Web.UI.Control.OnLoad(EventArgs e) +95 
    System.Web.UI.Control.LoadRecursive() +59 
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2952 
+0

Foreach 루프 중에 SingleOrDefault를 사용하면 다른 데이터 명령을 실행하려고하는지 궁금합니다. 최적이 아닐지라도 foreach (updateICAT.ToList()에서 ICAT icat)와 같이 updateICAT.ToList()를 호출하면 목록을 렌더링하고 내부 DataReader를 릴리스하므로 SingleOrDefault에 사용할 수 있습니다. 또는 새 컨텍스트를 할당하고 그런 식으로 ICAT에 다시 액세스 할 수 있습니다. –

+0

@DanielD. 나는 이것에 대해 꽤 이해하지 못한다. 더 설명하거나 예제를 보여줄 수 있습니까? 고맙습니다. – SadLife

답변

0

내가 LINQ는 IEnumerable foreach 루프 내부의 updateICAT.SingleOrDefault의 사용을 생각하고 있어요 : 아래

var updateCurrentICAT = updateICAT.SingleOrDefault(p => p.ICATID == counter); 

는 스택 추적입니다에

private static void updateICAT(DataSet s) 
    { 
     DataTable excelTable = s.Tables[7]; 
     DataTable contacts = getXML(); 

     Context _db = new Context(); 
     var updateICAT = _db.ICATs; 

     int counter = 1; 

     foreach(ICAT icat in updateICAT) 
     { 

      if(icat.ICATName != "--NOT AVAILABLE--") 
      { 
       DataRow r = contacts.Select("ICATName='" + excelTable.Rows[counter].ItemArray[2].ToString().Trim() + "'")[0]; 
       if (icat.ICATName != excelTable.Rows[counter].ItemArray[0].ToString()) 
       { 

        System.Diagnostics.Debug.WriteLine("not match"); 
        System.Diagnostics.Debug.WriteLine("current Icat id " + icat.ICATID + " current counter " + counter); 
        var updateCurrentICAT = updateICAT.SingleOrDefault(p => p.ICATID == counter); 
        updateCurrentICAT.ICATName = excelTable.Rows[counter].ItemArray[0].ToString().Trim(); 
        updateCurrentICAT.MEGroup = excelTable.Rows[counter].ItemArray[1].ToString().Trim(); 
        updateCurrentICAT.EscalationDisplayName = excelTable.Rows[counter].ItemArray[2].ToString().Trim(); 
        updateCurrentICAT.EscalationUserName = r["Username"].ToString().Trim(); 
        updateCurrentICAT.EscalationMail = r["Mail"].ToString().Trim(); 
       } 
      } 
      counter++; 
     } 
    } 

오류는 문제. 이 문제를 해결할 수있는 한 가지 방법은 두 번째 Context을 사용하고 아래에 표시된 루프 내에서 db2.ICATs.SingleOrDefault을 호출하는 것입니다.

+0

고마워. 이것은 내가 만나는 오류를 해결합니다. – SadLife

관련 문제