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

时间:2013-04-04 13:48:41

标签: c# linq c#-4.0 datatable

我有一堆DataTables需要转换为object[,]数组(不是 object[][]数组)。在性能方面,最有效的方法是什么?

我知道我可以通过最初构建我的object[dt.Rows.Count, dt.Columns.Count],然后循环遍历行并将每行解析到数组中的某个位置来完成此操作,但我很确定还有其他方法,例如使用Linq或System。特定于数据的功能,例如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

1 个答案:

答案 0 :(得分:8)

基本上我们需要:

  1. object[,]

    分配内存

    我们在这里做不了多少..我们需要确保一次分配内存而不是再次重新分配。所以我们显然需要一次创建数组,而不需要使用内部重新分配内存块的List.Add(...)等操作。

  2. 然后,我们需要将对象从行项复制到多维数组中。我们在使用对象时无法使用Buffer.BlockCopy。当然,我们不能依赖任何memcpy类似的行为,因为每个对象的CLR需要复制其引用,或者在堆 - >&gt;框中为值类型执行unbox-&gt;复制。所以,最简单的方法就是... for .. style。

  3. 所以,看起来这里的大多数性能解决方案都是直观的:

    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;
    }