3

我有一个带有一些 DataTables 的 DataSet,这些 DataTables 与 DataRelations(经典订单 Header/Detail 对)链接在一起。有没有一种简单的方法可以将整个批次非规范化为具有相关表的所有列的单个 DataTable?

表名和列在编译时是未知的,可能有两个以上的表/关系。

4

2 回答 2

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]);
        }
    }
}
于 2009-09-02T10:44:30.483 回答
0

我不认为数据集本身就支持这一点,但在代码中很容易做到。

首先,您应该创建一个空数据表,然后从要合并的两个表中添加您需要的所有列。

然后,您逐步浏览主表中的数据,并逐步浏览相关表中的所有相关行。对于相关表中的每一行,您在新表中创建一个新行,并将两个数据行中的数据插入到新行中。

我现在无法访问这里的视觉工作室,但你明白了。

于 2009-02-06T21:26:09.310 回答