2010-12-06 6 views
4

세 개의 열의 값이 고유한지 확인하려는 DataTable이 있습니다. 그렇지 않은 경우 마지막 열은 값 조합의 첫 번째 줄 번호로 채워야합니다. 예를 들어DataTable에서 고유하지 않은 행을 표시합니다.

이 테이블 :

ID Name LastName Age Flag 
------------------------------------- 
1  Bart Simpson  10  - 
2  Lisa Simpson  8  - 
3  Bart Simpson  10  - 
4  Ned  Flanders 40  - 
5  Bart Simpson  10  - 

이 결과로 연결되어야 :

Line Name LastName Age Flag 
------------------------------------- 
1  Bart Simpson  10  - 
2  Lisa Simpson  8  - 
3  Bart Simpson  10  1 
4  Ned  Flanders 40  - 
5  Bart Simpson  10  1 

나는 두 개의 중첩 for 루프와의 DataTable을 반복하고 값을 비교하여이를 해결했다. 소량의 데이터에 대해서는 정상적으로 작동하지만 DataTable에 많은 행이 포함되어 있으면 매우 느립니다..

내 질문입니다 : 데이터의 양이 100과 20000 행 사이에 달라질 수 있다는 점에서이 문제에 대한 최상의/가장 빠른 솔루션은 무엇입니까?
LINQ를 사용하여이 작업을 수행 할 수 있습니까? (나는 그것에 익숙하지 않지만 배우고 싶다!)

답변

0

좋아요, 제 대답은 나 자신이라고 생각합니다. James Wiseman의 대답을 바탕으로 LINQ를 통해 뭔가를 시도했습니다.

Dim myErrnrFnct = Function(current, first) If(first <> current, first, 0) 
Dim myQuery = From row As DataRow In myDt.AsEnumerable _ 
         Select New With { _ 
         .LINE = row.Item("LINE"), _ 
         .NAME = row.Item("NAME"), _ 
         .LASTNAME = row.Item("LASTNAME"), _ 
         .AGE = row.Item("AGE"), _ 
         .FLAG = myErrnrFnct(row.Item("LINE"), myDt.AsEnumerable.First(Function(rowToCheck) _ 
                         rowToCheck.Item("NAME") = row.Item("NAME") AndAlso _ 
                         rowToCheck.Item("LASTNAME") = row.Item("LASTNAME") AndAlso _ 
                         rowToCheck.Item("AGE") = row.Item("AGE")).Item("LINE")) _ 
         } 

이 쿼리를 사용하면 질문에 설명 된 결과를 정확하게 얻을 수 있습니다. 동일한 값을 가진 다른 행이 없을 경우 열이 0 값을 갖기를 원하기 때문에 함수가 필요합니다.

내가 여기에 설명 된 일부 확장 추가했다, 다시 myQuery 중 DataTable을 효율적으로 활용하려면 다음 작업을 수행
How to: Implement CopyToDataTable Where the Generic Type T Is Not a DataRow
그리고 다음을이 행 할 것입니다 :

Dim myNewDt As DataTable = myQuery.CopyToDataTable() 

이 잘 작동하는 것 같다. 이 작업을 더 효과적으로 수행 할 수있는 제안이 있습니까?

2

C#/VB에서 데이터 테이블을 사용하는 방법에 대해서는 언급 할 수 없지만 모든 것을 SQL로 옮길 수 있다면 쿼리는 다음과 같습니다.

declare @t table (ID int, Name varchar(10), LastName varchar(10), Age int) 
insert into @t values (1,  'Bart' , 'Simpson',  10) 
insert into @t values (2,  'Lisa', 'Simpson' ,  8) 
insert into @t values (3,  'Bart', 'Simpson' , 10) 
insert into @t values (4,  'Ned',  'Flanders' , 40) 
insert into @t values (5 , 'Bart', 'Simpson' , 10) 

select t.*, 
(select min(ID) as ID 
    from @t t2 
    where t2.Name = t.Name 
    and t2.LastName = t.LastName 
    and t2.id < t.id) 
from @t t 

여기서 데모 용 테이블을 정의했습니다. 이것을 LINQ로 번역 할 수 있을지도 모릅니다.

+0

감사합니다. 서브 선택 (+1)을 사용하면 좋습니다. 그러나 나는 SQL을 필요로하지 않는 솔루션을 선호합니다. 나는 linq에서 이런 식으로하려고합니다. –

관련 문제