2011-08-29 3 views
2

저는 C#을 픽업하려고하는 VFP 개발자입니다. 가장 빠른 학습 방법은 일을하는 것이라고 생각하면서 연습을위한 작은 프로젝트를 나에게주었습니다.잠시 동안 foreach 루프로 이상한 동작이 발생합니다. READ()

목적

이동 아카이브 데이터베이스에 "라이브"데이터베이스에서 일부 트랜잭션.

일반적인 생각이었다 :

  • 는 "적합"채용 (부모)의 목록을 얻으려면 다음 하나) 그 하나 (읽기.
  • foreach 루프를 사용하여 하위 테이블 목록을 처리하고 내역 데이터베이스에 새 레코드를 삽입 한 다음 이전 테이블 을 "라이브"테이블에서 삭제합니다. 실제 작업 (부모가) 보관하는
  • 이동 후 ....

것들, 시작에 OK 갔다 그때 갑자기 벽돌 벽에 충돌 "라이브"에서

문제를 삭제 나는 부모의 기본 키를 저장하는 데 사용 RefCombo라는 변수가

,이 바로 while (READ()) 문 뒤에 그냥 foreach 루프 전에 저장됩니다. 네 개의 레코드의 테스트 데이터베이스에서

의 RefCombo 필드는 있었어야 : 내 미리 정의 된 목록

  • 과정 ChildTable1

    에서

    foreach는 childtable 작업 1 :

    동안은() 결과를 읽어

  • 과정 childTable2

  • ,211,

    프로세스 ChildTable3

  • 프로세스 ChildTable4

  • ChildTable5 프로세스는

다음 작업 2, 및 Job3 Job4으로 반복.

나에게 견과류를 어떻게되어 운전의 I이 대신 받고 있어요 :

동안 읽고() 결과 : 내 미리 정의 된 목록

  • 과정 ChildTable1

  • 에서 작업 1

    foreach는 childtable

    SKIP 다른 ChildTables, RefCombo (기본 키)가 Job2가되고 while read()

    0123으로 되돌아갑니다.

작업이 Job2로 변경되면 예상대로 작동하여 남아있는 각 상위 레코드에 대해 모든 하위 테이블을 반복합니다.

"현재 TransactionScope가 이미 완료되었습니다." 웹 페이지를 실행할 때마다 오류가 발생했습니다. 이 문제는 프로그램 시작시 connection.open() 부분에서 발생하지만 항상 발생하지 않으므로 핀 고정하기는 어렵습니다.

코드를 하단에 게시했습니다. 코드는 약간 씩보기에 좋지만 도움이된다면 많은 도움이 될 것입니다. 나는이 일을 2 일 동안하고 있었고 정말로 더 이상 머리카락을 잃을 여유가 없다. 내 코드에

모든 의견도 환영이 많은 것, 나는 C#을 정말 새로 온 사람과 모든 비트는 데 도움이 : P 미리

감사합니다.

#region Declaration 
DateTime FromDate = Convert.ToDateTime("01/01/2011"); 
DateTime ToDate = Convert.ToDateTime("01/03/2011"); 
string conStrSource = @"Data Source=HOME\SQLEXPRESS;Initial Catalog=MCC_Live;Integrated Security=True"; 

// Declare a list of child tables to check and move together with the Job 
List<String> TablesToMove = new List<String>(); 
    { 
    TablesToMove.Add("JobItems"); 
    TablesToMove.Add("JobTerms"); 
    TablesToMove.Add("JobMessages"); 
    TablesToMove.Add("JobCalcs"); 
    TablesToMove.Add("JobContainers"); 
    TablesToMove.Add("JobMetrics"); 
    } 
#endregion 

#region Set SQL String 
string QueryString = 
    "SELECT " + 
    "JobMaster.BranchID, JobMaster.JobNo, " + 
    "JobMaster.ImportDate, PermitStatus.CurrentStatus " + 
    "FROM JobMaster. " + 
    "INNER JOIN PermitStatus ON " + 
     "JobMaster.BranchID = PermitStatus.BranchID AND " + 
     "JobMaster.JobNo = PermitStatus.JobNo " + 
    "WHERE " + 
     "(JobMaster.ImportDate BETWEEN @FromDate AND @ToDate) AND " + 
     "PermitStatus.currentStatus NOT IN ('HT0', 'HT1', 'HT2')"; 
#endregion 

// Display on web page for reference 
ASPxFromDate.Value = FromDate; 
ASPxToDate.Value = ToDate; 
ASPxMemo1.Value = QueryString; 

#region Open Connection, Get List of filtered Master Jobs 
using (SqlConnection connection = new SqlConnection(conStrSource)) 
    { 
     int JobCount = 0; 
     ASPxListBox1.Items.Clear(); 
     ASPxListBox2.Items.Clear(); 
     ASPxListBox3.Items.Clear(); 
     ASPxListBox1.Columns.Clear(); 

     SqlCommand command = new SqlCommand(QueryString, connection); 
      { 
      command.Parameters.Add(new SqlParameter("@FromDate", FromDate)); 
      command.Parameters.Add(new SqlParameter("@ToDate", ToDate)); 
      } 
     connection.Open(); 
     SqlDataReader FilteredJobList = command.ExecuteReader(); 

#endregion 

     try // Process MasterJob File 
     { 
     // Process individual jobs one by one so I won't tie up memory and have better logging 
     while (FilteredJobList.Read()) 
      { 
      #region Declare variables 
      string RefCombo = (string)FilteredJobList[0] + (string)FilteredJobList[1]; //Get primary key 
      JobCount = JobCount + 1; 
      ASPxTextBox2.Value = JobCount; 
      ASPxListBox2.Items.Add(RefCombo); 
      #endregion 

      // Start transaction scope 
      TransactionScope TranScope = new TransactionScope(); 
       { 
       try 
        { 
        // Loop through child tables 
        foreach (string CurrentTable in TablesToMove) 
         { 
         #region Transfer child tables 
         // update list so I know which part its working on 
         ASPxListBox1.Items.Add(CurrentTable); 
         RefCombo = (string)FilteredJobList[0] + (string)FilteredJobList[1]; 
         string RefTableNow = (string)CurrentTable; 
         bool CancelTrans = false; 
         MoveChild(ref RefCombo, ref RefTableNow, ref conStrSource, ref CancelTrans); 
          if (CancelTrans == false) 
           { //LogFailure(); 
           break; 
           } 
         DelChild(ref RefCombo, ref RefTableNow, ref conStrSource, ref CancelTrans); 
          if (CancelTrans == false) 
           { //LogFailure(); 
           break; 
           } 
         #endregion 
          // Remove remaing entries 
          //MoveLatestStatus(); 
          //DeleteLatestStatus(); 
          //MoveMasterJob(); 
          //DeleteMasterJob(); 
          //LogSuccess(); 
          TranScope.Complete(); 
         } 
       catch 
        { 
        //LogFailure(); 
        } 
       } 
      } 
     finally 
      { 
       FilteredJobList.Close(); 
      } 
     } 
    } 


//------------------------------------------------------------------------------------------------ 

private void MoveChild(ref string RefCombo, ref string CurrentTable, ref string conStrSource, ref bool CancelTrans) 
    { 
    #region Define Insert String 
    string InsertSqlString = 
     "INSERT INTO [MCC_History].[dbo].[" + @CurrentTable + "]" + 
     " SELECT * FROM [MCC_Live].[dbo].[" + @CurrentTable + "] s" + 
     " WHERE NOT EXISTS" + 
     " (SELECT 1 FROM [MCC_History].[dbo].[" + @CurrentTable + "] t2" + 
     " WHERE t2.BranchID + t2.JobNo = s.BranchID + s.JobNo)" + 
     " AND s.BranchID + s.JobNo = @RefCombo"; 

    #endregion 

    #region Open connection and execute query 
    using (SqlConnection MoveConnect = new SqlConnection(conStrSource)) 
     { 
     try 
      { 
      SqlCommand InsertCommand = new SqlCommand(InsertSqlString, MoveConnect); 
       { 
       InsertCommand.Parameters.Add(new SqlParameter("@RefCombo", RefCombo)); 
       } 
      MoveConnect.Open(); 
      InsertCommand.ExecuteNonQuery(); 
      } 
     catch 
      { 
      CancelTrans = true; 
      } 
     } 
    #endregion 
    } 

//------------------------------------------------------------------------------------------------ 

private void DeleteChild(ref string RefCombo, ref string CurrentTable, ref string conStrSource, ref bool CancelTrans) 
    { 
    #region Define Delete query 
    string DeleteSqlString = 
     " DELETE FROM [MCC_Live].[dbo].[" + @CurrentTable + "]" + 
     " WHERE [MCC_Live].[dbo].[" + @CurrentTable + 
     "].BranchID + [MCC_DB].[dbo].[" + @CurrentTable + "].JobNo = @RefCombo"; 
    #endregion 

    #region Execute Delete query 
    using (SqlConnection MoveConnect = new SqlConnection(conStrSource)) 
     { 
     try 
      { 
      SqlCommand InsertCommand = new SqlCommand(DeleteSqlString, MoveConnect); 
       { 
       InsertCommand.Parameters.Add(new SqlParameter("@RefCombo", RefCombo)); 
       } 
      MoveConnect.Open(); 
      InsertCommand.ExecuteNonQuery(); 
      } 
     catch 
      { 
      CancelTrans = true; 
      } 
     } 
    #endregion 
    } 
+0

"현재 TransactionScope가 이미 완료되었습니다." 오류는 asp.net 설정과 관련이 있어야합니다. 일부 코드는 다른 코드와 달리 메모리에 보관됩니다. 코드에서 오류를 드릴 다운하려면 작은 동작과 여러 단계로 코드를 찹니다. 이 거대한 목록은 물마루 걷기에는 너무 어렵습니다. 이 코드를 호출하는 asp.net 코드도 추가해야합니다. 이 방법이 정말로 명확하지 않습니다. – CodingBarfield

+0

할거야, 고마워. :) 적어도 지금 나는 어디에서 검색을 시작할 지 안다. – Permas

답변

0

문제가있는 곳은 TranScope.Complete();입니다. foreach 루프 내부에 있으며 Foreach 블록이 종료 된 후에 속합니다. 목록의 첫 번째 반복이 끝나면 거래가 완료됩니다. 이렇게하면이 트랜잭션을 통해 더 이상 명령을 작성할 수 없습니다.

관련 문제