【问题标题】:What's the most efficient way to convert a DataTable to an object[,]?将 DataTable 转换为 object[,] 的最有效方法是什么?
【发布时间】:2013-04-04 13:48:40
【问题描述】:

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

我知道我可以通过最初构建我的object[dt.Rows.Count, dt.Columns.Count] 来做到这一点,然后遍历行并将每一行解析到数组中的一个位置,但我相当确定还有其他方法,例如使用 Linq 或 System.Data- dataRow.ToItemArray() 等特定功能可能更有效。

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

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

ID 名称 日期 值 1 雷切尔 2013 年 1 月 1 日 00:00:00 100.0000 2 约瑟夫 2012 年 3 月 31 日 00:00:00 50.0000 3 莎拉 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

【问题讨论】:

  • 使用 LINQ 并不能神奇地加快速度。
  • 通过“更高效”,您是否希望提高算法的时间复杂度(如 O(n^2) 到 O(n)),或者只是一个常数因子改进?
  • 为什么不在帖子中包含“之前”和“之后”数据?
  • @SteveWellens 当然,已添加
  • "converted to object[,]" "包含需要适当格式化的日期和数字" 这很令人困惑,如果你有一个对象数组,你就不会得到格式化。您是否希望将所有内容都转换为格式化的字符串,然后再转换为对象?我想你会手工编码这些东西。

标签: c# linq c#-4.0 datatable


【解决方案1】:

基本上我们需要:

  1. object[,]分配内存

    我们在这里无能为力.. 我们需要确保我们分配一次内存,而不是再次重新分配它。所以很明显,我们需要立即创建数组,而不使用像 List.Add(...) 这样在内部重新分配内存块的操作。

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

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

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

【讨论】:

    猜你喜欢
    • 2015-04-14
    • 1970-01-01
    • 2023-04-11
    • 2020-01-15
    • 2011-05-29
    • 2018-11-30
    • 2020-10-24
    • 1970-01-01
    • 2021-10-24
    相关资源
    最近更新 更多