Денормализовать набор данных - PullRequest
3 голосов
/ 07 февраля 2009

У меня есть DataSet с некоторыми DataTables, которые связаны вместе с DataRelations (пара заголовок / деталь классического порядка). Есть ли простой способ денормализовать весь лот в единую таблицу данных со всеми столбцами связанных таблиц?

Имена и столбцы таблиц неизвестны во время компиляции, и может быть более двух таблиц / отношений.

Ответы [ 2 ]

2 голосов
/ 02 сентября 2009

У меня была такая же проблема, но, поскольку на этот вопрос не было ответа, мне пришлось написать денормализатор. Оказалось, что это было не так уж и сложно - так что это первое сокращение, которое вы (или кто-то еще, кто столкнулся с этой проблемой) могли бы использовать / расширить:

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 голосов
/ 07 февраля 2009

Я не думаю, что наборы данных поддерживают это изначально, но это достаточно просто сделать в коде.

Сначала вы должны создать пустую таблицу данных, а затем добавить все нужные вам столбцы из обеих таблиц, которые хотите объединить.

Затем вы просматриваете данные в своей главной таблице и просматриваете все связанные строки из связанной таблицы. Для каждой строки в связанной таблице вы создаете новую строку в новой таблице и вставляете данные из обеих строк данных в новую.

У меня сейчас нет доступа к визуальной студии, но вы поняли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...