2009-06-22 2 views
1

편집 :이 버그가 .NET 버그인지 아닌지 여부에 관계없이 모든 의견을 보내 주시면 감사하겠습니다.DataTable API의 버그입니까? 변경 내용은 "잘못된 순서"로 저장/실행됩니다.

내가 예를 들어, 기본 키가 연속 유지해야합니다 DataTable을을 가지고 :

는 나는 다음과 같은 시나리오를 단순화하기 위해 관리했습니다 버그가 다른 행 사이에 행을 삽입 할 경우 공백을 만들기 위해 연속 행의 ID를 증가시킨 다음 행을 삽입해야합니다.

행을 삭제하는 경우 테이블의 행에 의해 남겨진 간격을 채우기 위해 연속 행의 ID를 감소시켜야합니다. ID가 1, 2 및 3

다음 삭제 ID = 2 및 설정 ID = 2 ID = 3의 표에서 3 행 올바르게

시작 작동

테스트 케이스 (간격을 메우기 위해); 이것은 올바르게 작동합니다. dataTable.GetChanges()에는 삭제 된 행과 수정 된 행이 포함됩니다. dataAdapter.Update (table)을 실행하면 잘 실행됩니다. 만약 2 행 IDS (1, 2), 다음으로 설정 ID = 3 ID = 2, 삽입 ID = 2하고 커밋 (시작하면 그러나

작동하지 않는

테스트 케이스 또는 수락) 변경. 이것은 이제 첫 번째 테스트와 동일한 상태 여야합니다.

그런 다음 ID = 2를 삭제하고 ID = 2 인 ID = 2로 설정하는 것과 같은 단계를 수행하지만 이제는 dataTable.GetChanges()의 순서가 잘못되었습니다. 첫 번째 행은 수정 된 행이고 두 번째 행은 삭제 된 행입니다. 그런 다음 dataAdapter.Update (table)를 시도하면 기본 키 위반이 발생합니다. 삭제하기 전에 기존 행을 수정하려고했습니다.

해결

내가 그렇게 행이 처음으로 최선을 다하고, 다음 행을 수정 한 다음 행을 추가 삭제가 강제, 문제에 대한 해결의 즉를 생각할 수 있습니다. 그러나 이것이 왜 일어나는 것입니까? 다른 해결책이 있습니까?

사전과 비슷한 "문제"를 보았습니다. 사전에 항목을 추가하고 삭제 한 다음 다시 삽입하면 열거 한 순서와 같지 않을 것입니다. 사전).

[Test] 
public void GetChanges_Working() 
{ 
    // Setup ID table with three rows, ID=1, ID=2, ID=3 
    DataTable idTable = new DataTable(); 
    idTable.Columns.Add("ID", typeof(int)); 

    idTable.PrimaryKey = new DataColumn[] { idTable.Columns["ID"] }; 

    idTable.Rows.Add(1); 
    idTable.Rows.Add(2); 
    idTable.Rows.Add(3); 

    idTable.AcceptChanges(); 

    // Delete ID=2, and move old ID=3 to ID=2 
    idTable.Select("ID = 2")[0].Delete(); 
    idTable.Select("ID = 3")[0]["ID"] = 2; 

    // Debug GetChanges 
    foreach (DataRow row in idTable.GetChanges().Rows) 
    { 
     if (row.RowState == DataRowState.Deleted) 
      Console.WriteLine("Deleted: {0}", row["ID", DataRowVersion.Original]); 
     else 
      Console.WriteLine("Modified: {0} = {1}", row["ID", DataRowVersion.Original], row["ID", DataRowVersion.Current]); 
    } 

    // Check GetChanges 
    Assert.AreEqual(DataRowState.Deleted, idTable.GetChanges().Rows[0].RowState, "1st row in GetChanges should be deleted row"); 
    Assert.AreEqual(DataRowState.Modified, idTable.GetChanges().Rows[1].RowState, "2nd row in GetChanges should be modified row"); 
} 

출력 :

Deleted: 2 
Modified: 3 = 2 

1 passed, 0 failed, 0 skipped, took 4.27 seconds (NUnit 2.4). 

다음 시험 :

[Test] 
public void GetChanges_NotWorking() 
{ 
    // Setup ID table with two rows, ID=1, ID=2 
    DataTable idTable = new DataTable(); 
    idTable.Columns.Add("ID", typeof(int)); 

    idTable.PrimaryKey = new DataColumn[] { idTable.Columns["ID"] }; 

    idTable.Rows.Add(1); 
    idTable.Rows.Add(2); 

    idTable.AcceptChanges(); 

    // Move old ID=2 to ID=3, and add ID=2 
    idTable.Select("ID = 2")[0]["ID"] = 3; 
    idTable.Rows.Add(2); 

    idTable.AcceptChanges(); 

    // Delete ID=2, and move old ID=3 to ID=2 
    idTable.Select("ID = 2")[0].Delete(); 
    idTable.Select("ID = 3")[0]["ID"] = 2; 

    // Debug GetChanges 
    foreach (DataRow row in idTable.GetChanges().Rows) 
    { 
     if (row.RowState == DataRowState.Deleted) 
      Console.WriteLine("Deleted: {0}", row["ID", DataRowVersion.Original]); 
     else 
      Console.WriteLine("Modified: {0} = {1}", row["ID", DataRowVersion.Original], row["ID", DataRowVersion.Current]); 
    } 

    // Check GetChanges 
    Assert.AreEqual(DataRowState.Deleted, idTable.GetChanges().Rows[0].RowState, "1st row in GetChanges should be deleted row"); 
    Assert.AreEqual(DataRowState.Modified, idTable.GetChanges().Rows[1].RowState, "2nd row in GetChanges should be modified row"); 
} 

출력 :

0 여기서

문제를 보여 두 NUnit를 시험이다

답변

2

이것은 버그가 아니며 요점은 당신이 (매우) 비표준 방식으로 ID를 사용하고 있다는 것입니다. 두 개의 대답 :

1) DataTable.GetChanges (DataRowState.수정 됨)을 업데이트 순서대로 처리합니다 (삭제, 수정, 삽입 될 것으로 생각합니다). 이것은 마스터/디테일 관계 (.net 3.0 이전)와 마찬가지로해야합니다. (예 .net 3.0)

2) 디자인을 다시 생각해보십시오. 일반적으로 ID는 불변이어야하며 간격 등을 허용해야합니다. 이렇게하면 모든 데이터베이스 작업이 많이 이루어집니다. 더 안정적이고 훨씬 쉽게. 다른 열을 사용하여 사용자에게 표시 할 순차 번호를 유지할 수 있습니다.

+0

+1 "일반 ID는 변경 불가능해야 함"및 "다른 열을 사용하여 사용자에게 표시 할 순차 번호를 유지할 수 있음". – TcKs

+0

기본 키가 이런 식으로 사용되어서는 안된다는 귀하의 요지를 보았습니다. 하지만 DataTable이 이상하게 작동하는 것처럼 보입니다. 즉,이 방법을 사용하면 작동해야합니다. DataAdapter.Update의 기본 동작이 삭제되었거나 수정 된 다음 삽입 된 순서로 처리되지 않는 이유는 무엇입니까? (BTW는 제가 임시 해결책으로 입력하려고했던 명령입니다 - 지금 원본 텍스트로 수정했습니다). – RickL

+0

@Rick : 어댑터에는 '제한적인'기능이 있습니다 (즉, 관계를 처리 할 수 ​​없음). 그래서 어떤 것이 비표준이라면 직접 처리해야합니다. –

관련 문제