2013-08-29 4 views
3

목표는 데이터 소스에서 데이터를 검색하고 일부 메타 데이터를 추가 한 다음 다른 대상에 삽입하는 것입니다.DataReader에 열을 추가하는 방법

대상에는 소스가 4 개인 열 (계산 열)이있는 스키마가 있습니다.

모든 열 (4 개 계산 포함)이있는 판독기가 필요한 SqlBulkCopy을 사용하고 있습니다.

DataReader에 수동으로 열을 추가 할 수있는 방법이 있습니까? 또는 데이터 삽입에 대한 대안이 없다면 어떻게해야합니까?

답변

2

  • 당신의 자료 DataReader를 또는에서 결과를 반환하기 위해 필요에 따라
  • 재정 당신의 클래스 생성자에 인터페이스를 기존 DataReader를 추가를 IDataReader에 인터페이스를
  • 를 구현하는 자신의 클래스를 생성 할 수있다 자신의 계산 된 값을 반환하십시오.

아이디어를 얻으려면 간단한 구현이 될 수 있습니다. (대부분의 방법을 건너 뛰었습니다)

public class WrapperDataReader : IDataReader 
{ 
    private IDataReader reader; 

    public WrapperDataReader(IDataReader reader) 
    { 
     this.reader = reader; 
    } 

    public void Close() 
    { 
     reader.Close(); 
    } 

    public int Depth 
    { 
     get { return reader.Depth; } 
    } 

    public DataTable GetSchemaTable() 
    { 
     var schemaTable = reader.GetSchemaTable(); 
     // add your computed column to the schema table 
     schemaTable.Rows.Add(...); 
     return schemaTable; 
    } 

    public bool GetBoolean(int i) 
    { 
     return reader.GetBoolean(i); 
    } 

    public int GetOrdinal(string name) 
    { 
     if (name.Equals("displayName", StringComparison.InvariantCultureIgnoreCase)) 
      return 15; 
     return reader.GetOrdinal(name); 
    } 

    public string GetString(int i) 
    { 
     if (i == 15) 
      return String.Format("{0}, {1}", GetString(1), GetString(2)); // lastname, firstname 
     return reader.GetString(i); 
    } 

} 

업데이트 당신이 propably, 대신 DataTable에 걸리는 과부하를 사용할 수있는 WriteToServer 방법을 사용하고 있기 때문에

.

 var connectionString = "..."; 
     var copy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.Default); 
     copy.DestinationTableName = "Customers"; 

     var reader = new SqlDataReader(); 
     var table = new DataTable(); 
     table.Load(reader); 
     table.Columns.Add("DisplayName", typeof(string), "lastname, firstname"); 
     table.Columns.Add("CustomerCode", typeof(string)); 

     foreach (DataRow row in table.Rows) 
      row["CustomerCode"] = ((int)row["id"] + 10000).ToString(); 

     copy.WriteToServer(table); 
+0

나는 .. –

+0

당신이 정말로 GetBytes를 구현해야합니까() 메소드 자신에게 GetBytes 방법을 구현하기 위해 몇 가지 어려움을 겪고 있어요? 기본 DataReader에 메서드를 전달하지 않는 이유는 무엇입니까? 'Return reader.GetBytes (i, fieldOffset, buffer, bufferoffset, length); ' –

+1

@Yosi 실제로 GetBytes를 구현할 필요가 없으며'GetSchemaTable'과 같은 복잡한 요소도 필요하지 않습니다. 클래스는'SqlBulkCopy'를위한 래퍼 (wrapper)로서 클래스가 사용하는'IDataReader'의 유일한 메소드는'bool IsDbNull (int)','bool Read()','int GetOrdnal (string)','Object GetValue (int)', 및 속성'int FieldCount'. 다른 모든 것은'NotImplmentedException()'을 던져 버릴 수 있습니다. 나는 이것을 내 자신에게해야했고 그게 전부였습니다. –

1

데이터 판독기는 읽기 전용 구조이므로 수정할 수 없습니다. 대신 DataTable을 사용할 수 있습니다.

1

Datareader는 데이터 읽기 전용입니다. 해당 스키마 또는 값을 수정할 수 없습니다.

데이터 집합/DataTable은이 용도로 사용됩니다.

0

는 내가 현재 사용하고 있음을, 또 다른 가능한 해결책을 발견했습니다

  1. 당신이 DataReader 기존에서 다음 개체를 만듭니다
    IEnumerable<object[]> - 데이터
    List<Column>를 나타냅니다 - 데이터 DataReader의 열을 나타냅니다.

  2. 는 데이터를 수정하고 여분의 열
  3. 업데이트의 개체를 가져 반환 내가 성능을 향상시키기 위해 수율 반환을 사용

    • DataReader 수정 * 방법 AsDataReader(IEnumerable<object[]> updatedData,updatedColumns List<Column>) 만들기

      를 추가합니다.
관련 문제