DataRow를 복사하거나 복제하는 간단한 방법?


118

DataRow의 복제본을 만드는 간단한 방법을 찾고 있습니다. 해당 행의 스냅 샷을 찍고 저장하는 것과 같습니다. 그러면 원본 Row의 값은 자유롭게 변경할 수 있지만 변경되지 않는 다른 저장된 사본이 있습니다. 이것이 올바른 방법입니까?

DataRow Source, Destination;
// Assume we create some columns and fill them with values
Destination.ItemArray = Source.ItemArray;

이것은 Snapshot의 ItemArray 참조가 Source에있는 참조를 가리 키도록 설정합니까 아니면 실제로 별도의 복사본을 생성합니까? 대신 이것을해야합니까?

Destination.ItemArray = Source.ItemArray.Clone();

편집 : 두 번째 코드 조각이 실제로 컴파일되지 않는다고 생각합니다.


이해가 안 돼요. 한 테이블에서 다른 테이블로 데이터 행을 복사 하시겠습니까? 그렇다면 DataTable.ImportRow를 사용하는 것이 당신이 추구하는 것이라고 생각합니다.
Mo Patel

좋아, 내 질문의 요구가 이제 다시 작업 참조
폴 매튜스

2
일부 시나리오에서는 데이터 행 자체가 BeginEdit / EndEdit / CancelEdit를 사용한 트랜잭션 편집을 지원하기 때문에이 작업을 수행 할 필요가 없습니다. 또한 .RejectChanges를 호출 할 수 있습니다.
peterG 2014 년

답변:


185

ImportRow메서드 를 사용 하여 동일한 스키마를 사용하여 DataTable에서 DataTable로 행을 복사 할 수 있습니다 .

var row = SourceTable.Rows[RowNum];
DestinationTable.ImportRow(row);

최신 정보:

새로운 편집을 통해 다음을 믿습니다.

var desRow = dataTable.NewRow();
var sourceRow = dataTable.Rows[rowNum];
desRow.ItemArray = sourceRow.ItemArray.Clone() as object[];

작동 할 것이다


분명히 Clone ()은 얕은 복사본 만 제공합니다. 동일한 복사본을 만드는 데 충분하다고 생각하십니까? 아니면 딥 클론이 필요합니까?
Paul Matthews

5
@PaulMatthews : 운 좋게도 DataTable에는 ref 유형이 아닌 값 유형이 포함되어 있으므로 값 유형의 얕은 복사는 깊은 복사와 동일합니다
cuongle

16
이 게시물을 찾는 사람들을 위해 나는 자주 묻는대로 다음을 추가 할 것이므로 다른 사람들이 혼란 스러울 수 있습니다. 복제는 구조 만 복사하고, 복사는 구조를 복사 한 다음 데이터를 복사합니다. 즉, 두 테이블이 모두 인스턴스화되면 데이터를 복사하는 또 다른 쉬운 방법은 대상 테이블에 새 행을 만들고 다음을 사용하는 것입니다. destRow.ItemArray = sourceRow.ItemArray그런 다음 간단히 행을 다시 추가합니다.destTable.Rows.Add(destRow);
Franck

1
이 방법을 사용하여 데이터 행의 복제본을 얻으려고합니다. 다음 단계를 수행 한 다음 소스 행이 포함 된 데이터 테이블을 지우고 이제 빈 필드가있는 소스 행이 있습니다.
Sergеу Isupov

ImportRow 메서드를 사용하는 것이 저에게 효과적이라는 것을 알았습니다. NewRow 메서드는 그렇지 않았습니다.
OldDog

2

참고 : cuongle의 helfpul 답변 에는 모든 성분이 포함되어 있지만 솔루션을 간소화 할 수 있으며 (필요 없음 .ItemArray) 질문에 더 잘 일치하도록 재구성 할 수 있습니다.

특정 System.Data.DataRow인스턴스 의 (격리 된) 복제본을 생성하려면 다음을 수행 할 수 있습니다.

// Assume that variable `table` contains the source data table.

// Create an auxiliary, empty, column-structure-only clone of the source data table.
var tableAux = table.Clone();
// Note: .Copy(), by contrast, would clone the data rows also.

// Select the data row to clone, e.g. the 2nd one:
var row = table.Rows[1];

// Import the data row of interest into the aux. table.
// This creates a *shallow clone* of it.
// Note: If you'll be *reusing* the aux. table for single-row cloning later, call
//       tableAux.Clear() first.
tableAux.ImportRow(row);

// Extract the cloned row from the aux. table:
var rowClone = tableAux.Rows[0];

참고 : 값 유형 인스턴스 인 열 값과 함께있는 그대로 작동하는 얕은 복제가 수행 되지만 참조 유형 인스턴스를 포함하는 열 값의 독립적 인 복사본을 생성하려면 더 많은 작업이 필요 합니다 (이러한 독립적 인 복사본을 생성하는 것이 항상 가능한 것은 아닙니다. ).


1

일부 행만 필요하기 때문에 전체 DataTable을 복사본으로 유지하고 싶지 않은 것 같습니다. 테이블에서 선택하여 지정할 수있는 creteria가있는 경우 해당 행만 DataRow의 추가 백업 배열에 복사 할 수 있습니다.

DataRow[] rows = sourceTable.Select("searchColumn = value");

.Select () 함수에는 몇 가지 옵션이 있으며이 옵션은 예를 들어 SQL로 읽을 수 있습니다.

SELECT * FROM sourceTable WHERE searchColumn = value;

그런 다음 위에서 설명한대로 원하는 행을 가져올 수 있습니다.

targetTable.ImportRows(rows[n])

... 원하는 유효한 n에 대해 그러나 열은 각 테이블에서 동일해야합니다.

ImportRow에 대해 알아야 할 사항은 기본 키를 사용할 때 런타임 중에 오류가 발생한다는 것입니다!

먼저 기본 키 누락으로 인해 실패한 행이 이미 존재하는지 확인하고 싶었지만 항상 확인이 실패했습니다. 결국 기존 행을 완전히 지우고 원하는 행을 다시 가져 오기로 결정했습니다.

두 번째 문제는 무슨 일이 일어나는지 이해하는 데 도움이되었습니다. 가져 오기 기능을 사용하는 방법은 하나의 열에 교환 된 항목이있는 행을 복제하는 것입니다. 나는 그것이 항상 바뀌었고 여전히 배열의 행에 대한 참조라는 것을 깨달았습니다. 먼저 원본을 가져온 다음 원하는 항목을 변경해야했습니다.

참조는 또한 행이 실제로 두 배로 늘어났기 때문에 처음으로 행을 가져 오려고 할 때 나타나는 기본 키 오류를 설명합니다.


-4

그러나 새 테이블에서 새 행에 액세스 할 수 있는지 확인하려면 테이블을 닫아야합니다.

DataTable destination = new DataTable(source.TableName);
destination = source.Clone();
DataRow sourceRow = source.Rows[0];
destination.ImportRow(sourceRow);

3
두 번째 코드 줄이 변수를 다시 할당하면 첫 번째 코드 줄의 요점은 무엇입니까?
Erik Philips

이 답변은 더 많은 설명을 사용할 수 있으며 ( 테이블을 닫아야하는 것이 무엇 의미 하는지 모르겠습니다 ) @ErikPhilips에 요점 DataTable destination = source.Clone()이 있지만 ( 해야 할 일) 그렇지 않으면이 답변이 완벽 .ItemArray하고 허용되는 답변 의 접근 방식 보다 낫습니다 .
mklement0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.