我有一个DataSet,其中包含一些与DataRelations(经典订单标题/详细信息对)链接在一起的DataTable。是否有一种简单的方法可以将整个批次归一化为具有相关表的所有列的单个DataTable?
表名和列在编译时是未知的,并且可能有两个以上的表/关系。
答案 0 :(得分: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]);
}
}
}
答案 1 :(得分:0)
我认为数据集不支持本地,但在代码中很容易做到。
首先,您应该创建一个空数据表,然后从要组合的两个表中添加所需的所有列。
然后,您逐步浏览主表中的数据,并逐步查看相关表中的所有相关行。对于相关表中的每一行,您将在新表中创建一个新行,并将两个数据行中的数据插入到新行中。
我现在无法访问visual studio,但是你明白了。