2009-03-19 10 views
1

DataTable insertRows 키없이 데이터를 정규화하고 싶습니다. 그렇게하려면 ID (import_id)를 찾아 중복 기록을 확인하고 표시해야합니다. 그 후에 나는 별개의 것들만 선택할 것입니다. 내가 생각하고있는 접근법은 해당 행의 각 행을 해당 DataTable의 모든 행과 비교하는 것입니다. insertRowsDataTable의 모든 행을 비교 - 중복 레코드 식별

DataTable의 열은 디자인 타임에 알려지지 않았고 키가 없습니다. 성능면에서는 테이블이 10k에서 20k 레코드와 약 40 개의 열을 가지게됩니다.

성능을 크게 저하시키지 않으면 어떻게 달성 할 수 있습니까?

내가 LINQ를 사용하여 시도했지만 동적으로 내가 각 행에 대해 루프에서 이름과 성을 비교하고 여기에 를 Where 기준

foreach (System.Data.DataRow lrows in importDataTable.Rows) 
{ 
    IEnumerable<System.Data.DataRow> insertRows = importDataTable.Rows.Cast<System.Data.DataRow>(); 

    var col_matches = 
    from irows in insertRows 
    where 
    String.Compare(irows["fname"].ToString(), lrows["fname"].ToString(), true).Equals(0) 
    && 
    String.Compare(irows["last_name"].ToString(), lrows["last_name"].ToString(),true).Equals(0) 

    select new { import_id = irows["import_id"].ToString() }; 
} 

모든 아이디어를 환영을 지정하는 방법을 알고하지 않았다 . linq을 사용하여 유사한 열 이름을 찾으려면 어떻게해야합니까?> 내 비슷한 질문

+0

질문을 편집하고 "community wiki"의 선택을 취소하십시오 –

+0

이 게시물은 커뮤니티 위키이므로 어떤 투표도받지 못합니까? –

+0

위키를 선택 취소 할 수 없습니다. 죄송합니다. – kiev

답변

2

O (n)의 복잡성없이이 작업을 수행하는 가장 쉬운 방법은 Set 작업, 특히 Contains 작업을 효율적으로 구현하는 데이터 구조를 사용하는 것입니다. 다행히 .NET (3.0 현재)이 HashSet 개체가 포함되어 있습니다. 이 기능을 사용하려면 DataTable에 행을 캡슐화하는 단일 개체가 필요합니다.

DataRow가 작동하지 않으면 관련된 레코드를 문자열로 변환하고 연결하여 HashSet에 배치하는 것이 좋습니다. 행을 삽입하기 전에 HashSet에 이미 Contains가 들어 있는지 확인하십시오. 그럴 경우 중복 된 것을 발견했습니다.

편집 :

이러한 방법은 O (N)이다.

+0

이 솔루션은 잘 작동하고 O (n) – kiev

1

질문을 올바르게 이해할 수 있을지 모르겠지만 System.Data.DataTable을 다룰 때 다음과 같이 작동해야합니다.

for (Int32 r0 = 0; r0 < dataTable.Rows.Count; r0++) 
{ 
    for (Int32 r1 = r0 + 1; r1 < dataTable.Rows.Count; r1++) 
    { 
     Boolean rowsEqual = true; 

     for (Int32 c = 0; c < dataTable.Columns.Count; c++) 
     { 
     if (!Object.Equals(dataTable.Rows[r0][c], dataTable.Rows[r1][c]) 
     { 
      rowsEqual = false; 
      break; 
     } 
     } 

     if (rowsEqual) 
     { 
     Console.WriteLine(
      String.Format("Row {0} is a duplicate of row {1}.", r0, r1)) 
     } 
    } 
} 
+1

와우! 비싼 O (n^2) – Keltex

+0

이 방법을 구현했으며 여기에서 묻는 것을 성취합니다. 고맙습니다! 덜 비싼 접근 방식을 사용하는 솔루션을 계속 검토하고 있습니다. – kiev

0

나는 LINQ에 대해 너무 잘 알고 있지 않지만 .Distinct() 연산자를 사용할 수 있습니까?

http://blogs.msdn.com/charlie/archive/2006/11/19/linq-farm-group-and-distinct.aspx

귀하의 질문은 당신이 당신의 쿼리에서 제거 방법을 찾고 여부를 구체적으로 중복 행을 식별하는 데 필요 여부를 명확하게하지 않습니다. "Distinct"를 추가하면 여분의 인스턴스가 제거되지만 필요하다고 말할 수는 없습니다.

+0

행을 식별하려고합니다.이를 반영하기 위해 질문을 편집했습니다. – kiev