什么是将DataTable转换为对象的最有效方法[,]?

问题描述:

我有一堆DataTables需要转换为object[,]阵列(而不是object[][]阵列)。在性能方面做什么最有效的方法是什么?什么是将DataTable转换为对象的最有效方法[,]?

我知道我可以通过最初构建我的object[dt.Rows.Count, dt.Columns.Count]来完成此操作,然后遍历行并将每行解析到数组中的某个位置,但我确信还有其他方法,如使用Linq或System.Data特定诸如dataRow.ToItemArray()之类的特征可能更有效。

我的DataTables是可变大小的,并且包含日期和数字,除了字符串之外,还需要适当格式化。

例如,如果我的数据表中的一个包含

 
Id Name Date     Value 
1  Rachel 1/1/2013 00:00:00 100.0000 
2  Joseph 3/31/2012 00:00:00 50.0000 
3  Sarah 2/28/2013 00:00:00 75.5000 

然后我希望的object[,]阵列包含完全相同的数据(理想地与头),而是用格式的日期和值

arr[x,0] = row[x].Field<int>("Id"); 
arr[x,1] = row[x].Field<string>("Name"); 
arr[x,2] = row[x].Field<DateTime>("Date").ToString("M/d/yy"); 
arr[x,3] = row[x].Field<decimal>("Value").ToString("C2"); // Currency format 
+4

使用LINQ不会奇迹般地加快东西。 – 2013-04-04 13:54:38

+0

通过“更高效”,您是否希望改进算法的时间复杂度(如O(n^2)到O(n)),还是只是一个常数因子改进? – mbeckish 2013-04-04 13:55:18

+1

为什么你不在帖子中包含“之前”和“之后”的数据? – 2013-04-04 13:59:04

基本上,我们需要:

  1. 分配内存object[,]

    这里我们不能做太多的事情..我们需要确保一次分配内存,而不是重新分配一次。所以很明显我们需要一次创建数组,而不使用内部重新分配内存块的操作,如List.Add(...)

  2. 然后,我们需要将行项目中的对象复制到多维数组中。我们在这里处理对象时不能使用Buffer.BlockCopy。当然,我们不能依赖任何类似于memcpy的行为,因为每个对象的CLR都需要复制其引用,或者对于值类型执行unbox-> copy in heap-> box。所以,最简单的方法将只是.. for ..风格。

所以,看起来像极高性能的解决方案这里是一个直观:

public static object[,] Convert(DataTable dt) 
{ 
    var rows = dt.Rows; 
    int rowCount = rows.Count; 
    int colCount = dt.Columns.Count; 
    var result = new object[rowCount, colCount]; 

    for (int i = 0; i < rowCount; i++) 
    { 
     var row = rows[i]; 
     for (int j = 0; j < colCount; j++) 
     { 
      result[i, j] = row[j]; 
     } 
    } 

    return result; 
}