강좌와 팁

닷넷 : DataTable끼리 DataRow 복사하기 날짜:2020-3-7 5:35:35 조회수:42
작성자 : 소엔
포인트 : 1331
가입일 : 2020-02-02 00:09:14
방문횟수 : 67
글 182개, 댓글 49개
소개 : SoEn 운영자입니다.
작성글 보기
쪽지 보내기
큰 테이블을 쿼리하여 페이지별로 보여주는데 원격 쿼리인데다 대규모 테이블이어서 성능이 나오지 않는다. 그래서 페이지별로 쿼리하지 말고 전체를 가져온 후 잘라서 쓰기로 했다. 예를 들어 tblPeople에 8500개의 레코드가 있고 이걸 2000페이지씩 보여준다면 통째로 읽은 후 선두부터 2000개씩 잘라 사용하면 된다.

똑같은 구조의 DataTable을 만들고 페이지별로 레코드를 분할하는 문제이다. 테이블간의 구조 복사는 Clone 메서드로 간단히 처리할 수 있다. 데이터는 빼고 스키마와 제약까지 똑같은 테이블이 생성된다. 테이블별로 임의행을 구할 수 있으니 행을 읽어 새 테이블에 넣어 주기면 될 거라 생각했다. 다음 코드는 tblPeople의 첫 레코드를 복사하여 tblPage에 집어 넣는다.

DataTable tblPage;
tblPage = tblPeople.Clone();
DataRow datarow = tblPeople.Rows[0];
tblPage.Rows.Add(datarow);

return tblPage;

새 테이블 하나 만들고 Clone으로 복사하면 똑같은 구조의 사본 테이블을 만들어 준다. 아예 만들어 주므로 미리 DataTable 객체를 생성해 놓을 필요는 없다. 물론 테이블 내부는 텅텅 비어 있다. 이 안에 레코드를 가져와 채워 주면 된다. tblPeople의 Rows에서 레코드를 순서대로 가져온 후 tblPage의 Rows에 하나씩 집어 넣으면 간단히 될 것 같았지만 다음과 같은 예외가 발생했다.



남의 집 자식을 함부러 데려올 수 없다는 얘기다. 하긴 한 레코드를 두 테이블에서 소유하고 있으면 여러 가지 문제가 발생할 수 밖에 없다. 이 문제를 해결하려면 참조가 하닌 레코드의 복사본을 만들어야 한다. 그러나 DataRow 클래스에는 Clone 같은 메서드가 보이지 않았다. 찾아 보니 DataTable에 ImportRow라는 메서드가 똑같은 역할을 수행한다. DataRow 자체는 복사 메서드가 없지만 DataTable에 남의 레코드를 복사해 추가하는 메서드가 있다. 결과 코드는 다음과 같다.

DataTable tblPage;
tblPage = tblPeople.Clone();
tblPage.ImportRow(tblPeople.Rows[0]);

return tblPage;

ImportRow 메서드로 남의 레코드를 복사해 추가했으니 소유권 본쟁이 없고 이후에 각자 편집해도 영향을 받지 않는다. 남의 DataTable의 DataRow를 직접 가져올 수도 있고 Select한 DataRow[]에서 하나씩 꺼내 집어 넣어도 상관없다. Row의 구조만 같으면 누구의 DataRow이건 입양할 수 있다. 참고로 DataTable끼리 전체 레코드를 복사할 때는 Copy 메서드를 사용한다. Clone후 Copy하면 완전히 똑같은 사본이 생성된다.

최초 딱 한 번만 쿼리를 수행하여 전체 목록을 가져오니 오히려 속도가 더 빨라졌다. 페이지별로 Order By하고 Offset Fetch하는 것보다는 통쿼리가 웬만하면 더 빠르다. 어차피 Order By가 들어가면 전체 테이블을 다 읽는 것이나 마찬가지이다. 게다가 일단 가져오고 나면 모든 것이 메모리 내에서 일어나므로 페이지 전환도 신속하다.

DataRow를 2000개나 분할하여 복사하지만 거의 실시간으로 수행되며 다만 그리드에 바인딩하는 시간이 대략 1초 정도 걸렸다. 매 페이지마다 쿼리 날리는 것보다는 훨씬 이득이다. 다만 전체 레코드를 다 가지고 있으니 아무래도 메모리는 좀 더 먹는다. 이래서 속도와 사이즈는 항상 반비례 관계이다.

 



개발자의 천국 SoEn

목록보기 삭제 수정 신고 스크랩

henrietta 3월7일 5:49:54  

결국 필요에 따라 선택해야 하는 것이군요.

소엔 3월7일 5:58:21  

요즘은 메모리가 워낙 싸고 흔해서 메모리를 좀 많이 쓰는 쪽을 선택하는 것이 유리합니다.
옛날처럼 1바이트 아낄려고 몸부림칠 필요가 없습니다. 닷넷만 해도 시스템이 워낙 정교하고 효율적이어서 웬만한 작업은 순식간에 해 치웁니다. 그래서 개발하기 참 편해졌죠.


로그인하셔야 댓글을 달 수 있습니다.