我有一个类型为System.Data.DataTable的源数据表,我必须从中生成映射列的目标数据表(考虑映射列的相同SqlDBType。
我有一个 MappingInfo 类的列表,其中每个源数据表列都与将在目标数据表中的新列名称映射。
Public Class MappingInfo
Public Property SourceFieldName As String
Public Property DestinationFieldName As String
End Class
我必须评估源数据表中的条件以允许在目标表中复制行数据。
我使用以下代码片段执行此操作:
''Prepare destination table.
For Each oMapping In oMappingInfo
DestinationDataTable.Columns.Add( _
New DataColumn(oMapping.DestinationFieldName))
Next
For Each oRow In SourceDataTable.Rows ''Copy data.
If oRow("IsActive") Then
oDataRow = DestinationDataTable.NewRow
For Each oMapping In oMappingInfo
oDataRow(oMapping.DestinationFieldName) = _
oRow(oMapping.SourceFieldName)
Next
DestinationDataTable.Rows.Add(oDataRow)
End If
Next
主要缺点是,这里的源数据表中至少有 40k 条记录,并且无法从数据库中获取数据,因为只有在用户保存其工作时才提交数据,因此所有更改。生成的目标表将作为数据源分配给网格控件和报表以供预览。
我如何使用 Linq 有效地实现这一目标,或者有人请向我建议实现此要求的最佳方法。
尝试过这个,所以我不能确定它会更快,但在我看来,使用如下所示的东西你会得到更好的速度:
Dim l_destinationTable As DataTable
' This creates a copy of the structure and content
l_destinationTable = SourceTable.Copy()
For Each l_column As DataColumn in l_destinationTable.Columns
Dim l_columnMap = oMappingInfo.FirstOrDefault( _
Function (c) c.SourceFieldName = l_column.ColumnName )
If l_columnMap IsNot Nothing Then
' Rename the column if it is mapped
l_column.ColumnName = l_columnMap.DestinationFieldName
Else
' Drop the column if it is not mapped
l_destinationTable.Columns.Remove( l_column )
End If
Next
注意:如果未映射的列是关系的一部分,或者另一列的表达式依赖于此列,则此方法将失败。此外,如果要交换两列的名称(例如,A 将命名为 B,B 将命名为 A),那么您将收到异常,因为两列可能不能同时具有相同的名称。