向 DataTable 添加多行

10

我知道两种向DataTable中添加带有数据的新行的方法。

string[] arr2 = { "one", "two", "three" };
dtDeptDtl.Columns.Add("Dept_Cd");

for (int a = 0; a < arr2.Length; a++)
{
    DataRow dr2 = dtDeptDtl.NewRow();
    dr2["Dept_Cd"] = DeptCd[a];
    dtDeptDtl.Rows.Add(dr2);
}

for (int a = 0; a < arr2.Length; a++)
{
    dtDeptDtl.Rows.Add();
    dtDeptDtl.Rows[a]["Dept_Cd"] = DeptCd[a];
}

以上两种方法都会给我相同的结果,即将"One Two Three"添加到DataTable中的不同行。

但我的问题是这两个步骤之间有什么区别,并且哪个在性能方面更好呢?


您是否需要在现有数据表中添加新列? - cuongle
1
你可以像这样做:foreach (var item in arr2){ dtDeptDtl.Rows.Add(item);} - Damith
1
第一种方法会更快。 - Alex Filipovici
1
你能否请解释一下为什么? - Anuj
1个回答

11
反编译器的一些观察 在两种情况下,都使用了System.Data.DataRowCollection.Add方法的不同重载。
第一种方法使用的是:
public void Add(DataRow row)
{
    this.table.AddRow(row, -1);
}

第二种方法将使用:
public DataRow Add(params object[] values)
{
    int record = this.table.NewRecordFromArray(values);
    DataRow dataRow = this.table.NewRow(record);
    this.table.AddRow(dataRow, -1);
    return dataRow;
}

现在,看看这个小东西:

internal int NewRecordFromArray(object[] value)
{
    int count = this.columnCollection.Count;
    if (count < value.Length)
    {
        throw ExceptionBuilder.ValueArrayLength();
    }
    int num = this.recordManager.NewRecordBase();
    int result;
    try
    {
        for (int i = 0; i < value.Length; i++)
        {
            if (value[i] != null)
            {
                this.columnCollection[i][num] = value[i];
            }
            else
            {
                this.columnCollection[i].Init(num);
            }
        }
        for (int j = value.Length; j < count; j++)
        {
            this.columnCollection[j].Init(num);
        }
        result = num;
    }
    catch (Exception e)
    {
        if (ADP.IsCatchableOrSecurityExceptionType(e))
        {
            this.FreeRecord(ref num);
        }
        throw;
    }
    return result;
}

特别要注意的是,this.columnCollection[i][num] = value[i]; 这一行代码将会调用:
public DataColumn this[int index]
{
    get
    {
        DataColumn result;
        try
        {
            result = (DataColumn)this._list[index];
        }
        catch (ArgumentOutOfRangeException)
        {
            throw ExceptionBuilder.ColumnOutOfRange(index);
        }
        return result;
    }
}

继续往下看,我们发现实际上 _list 是一个 ArrayList
private readonly ArrayList _list = new ArrayList();

结论

总之,如果您使用的是dtDeptDtl.Rows.Add();而不是dtDeptDtl.Rows.Add(dr2);,则会出现性能下降,随着列数的增加,性能将呈指数级增长。造成性能下降的原因是调用了NewRecordFromArray方法,该方法在ArrayList上进行迭代。

注意:如果您向表中添加了8个列并在循环1000000次的for内执行一些测试,则可以轻松测试此问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接