2009-02-06 3 views
3

DataRelations (클래식 주문 헤더/세부 정보 쌍)와 함께 연결된 일부 DataTable이있는 DataSet이 있습니다. 관련 테이블의 모든 열을 사용하여 전체를 단일 DataTable로 역 정규화하는 쉬운 방법이 있습니까?데이터 세트 비정규 화

테이블 이름과 열은 컴파일시에는 알 수 없으며 두 개 이상의 테이블/관계가있을 수 있습니다.

답변

2

내 자신과 같은 문제가 있었지만이 질문에 대답이 없었기 때문에 나는 내 자신을 비정규 화기를 써야했습니다. 이렇게 어려운 일이 아니라는 사실이 드러났습니다. 따라서이 문제가 처음으로 발생했거나이 문제가 발생했을 수 있습니다.

public class DataSetDenormalizer 
{ 
    public void DenormalizeRelationships(DataSet dataSet) 
    { 
     IOrderedEnumerable<DataRelation> orderedRelationship = SortRelationshipsByNumberOfChildRows(dataSet); 
     var tablesToRemove = new List<DataTable>(); 

     foreach (DataRelation relationship in orderedRelationship) 
     { 
      DenormalizeColumns(relationship); 
      DenormalizeData(relationship); 
      RemoveDenormalizedRelationships(dataSet, relationship, tablesToRemove); 
     } 
    } 

    private IOrderedEnumerable<DataRelation> SortRelationshipsByNumberOfChildRows(DataSet dataSet) 
    { 
     var relationships = new List<DataRelation>(); 
     foreach (DataRelation relationship in dataSet.Relations) 
      relationships.Add(relationship); 
     return relationships.OrderBy(r => r.ChildTable.Rows.Count); 
    } 

    private void DenormalizeColumns(DataRelation relationship) 
    { 
     for (int columnIndex = 0; columnIndex < relationship.ParentTable.Columns.Count; ++columnIndex) 
     { 
      DataColumn column = relationship.ParentTable.Columns[columnIndex]; 
      if (relationship.ParentColumns.Contains(column)) continue; 
      relationship.ChildTable.Columns.Add(new DataColumn(column.ColumnName, column.DataType)); 
     } 
    } 

    private void DenormalizeData(DataRelation relationship) 
    { 
     for (int rowIndex = 0; rowIndex < relationship.ChildTable.Rows.Count; ++rowIndex) 
     { 
      DataRow row = relationship.ChildTable.Rows[rowIndex]; 
      DataRow parentRow = row.GetParentRow(relationship); 

      for (int columnIndex = 0; columnIndex < relationship.ParentTable.Columns.Count; ++columnIndex) 
      { 
       DataColumn column = relationship.ParentTable.Columns[columnIndex]; 
       if (relationship.ChildTable.Columns.Contains(column.ColumnName)) 
       { 
        row.SetField(column.ColumnName, parentRow[column]); 
       } 
      } 
     } 
    } 

    private void RemoveDenormalizedRelationships(DataSet dataSet, DataRelation relationship, List<DataTable> tablesToRemove) 
    { 
     dataSet.Relations.Remove(relationship); 
     relationship.ChildTable.Constraints.Remove(relationship.RelationName); 

     if (!tablesToRemove.Contains(relationship.ParentTable)) 
      tablesToRemove.Add(relationship.ParentTable); 

     int numberOfColumns = relationship.ChildColumns.Length; 
     for (int columnIndex = 0; columnIndex < numberOfColumns; ++columnIndex) 
     { 
      relationship.ChildTable.Columns.Remove(relationship.ChildColumns[columnIndex]); 
     } 
    } 
} 
0

데이터 세트가 기본적으로이를 지원한다고 생각하지 않지만 코드에서 수행하기는 쉽습니다.

먼저 빈 데이터 테이블을 만든 다음 필요한 모든 열을 결합하려는 두 테이블에서 모두 추가해야합니다.

그런 다음 주 테이블의 데이터를 단계별로 실행하고 관련 테이블의 모든 관련 행을 단계별로 실행합니다. 관련 테이블의 각 행에 대해 새 테이블에 새 행을 작성하고 두 데이터 행의 데이터를 새 테이블에 삽입합니다.

저는 여기 Visual Studio에 액세스 할 수 없지만 아이디어를 얻을 수 있습니다.