Workflow for Collection.Add ()

DataTable.Rows.Add () adds a row to the data table. However, how does it handle the underlying array?

When adding one row at a time, does the entire array restore every added row?

Or can it just modify an existing array without any impact on performance?

I am wondering if it is better to determine the size of the array before filling it with data or if some kind of data table can modify the collection without copying and moving things (behind the scenes).

His understanding is that to configure the array you need to redefine it and transfer the previously existing data into a new structure.

My question is: what is the workflow for the Collection.Add () method?

+3
source share
1

, , DotPeek:

DataTable.Rows.Add(DataRow row)
{
    this.table.AddRow(row, -1);
}

:

DataTable.AddRow(DataRow row, int proposedID)
{
    this.InsertRow(row, proposedID, -1);
}

:

DataTable.InsertRow(DataRow row, int proposedID, int pos)
{
    this.InsertRow(row, (long) proposedID, pos, true);
}  

:

DataTable.InsertRow(DataRow row, long proposedID, int pos, bool fireEvent)
{
    Exception deferredException = (Exception) null;
    if (row == null)
        throw ExceptionBuilder.ArgumentNull("row");
    if (row.Table != this)
        throw ExceptionBuilder.RowAlreadyInOtherCollection();
    if (row.rowID != -1L)
        throw ExceptionBuilder.RowAlreadyInTheCollection();
    row.BeginEdit();
    int proposedRecord = row.tempRecord;
    row.tempRecord = -1;
    if (proposedID == -1L)
        proposedID = this.nextRowID;
    bool flag;
    if (flag = this.nextRowID <= proposedID)
        this.nextRowID = checked (proposedID + 1L);
    try
    {
        try
        {
            row.rowID = proposedID;
            this.SetNewRecordWorker(row, proposedRecord, DataRowAction.Add, false, false, pos, fireEvent, out deferredException);
        }
        catch
        {
            if (flag && this.nextRowID == proposedID + 1L)
                this.nextRowID = proposedID;
            row.rowID = -1L;
            row.tempRecord = proposedRecord;
            throw;
        }
        if (deferredException != null)
            throw deferredException;
        if (!this.EnforceConstraints || this.inLoad)
            return;
        int count = this.columnCollection.Count;
        for (int index = 0; index < count; ++index)
        {
            DataColumn dataColumn = this.columnCollection[index];
            if (dataColumn.Computed)
                dataColumn.CheckColumnConstraint(row, DataRowAction.Add);
        }
    }
    finally
    {
        row.ResetLastChangedColumn();
    }
}

:

DataTable.SetNewRecordWorker(DataRow row, int proposedRecord, DataRowAction action, bool isInMerge, bool suppressEnsurePropertyChanged, int position, bool fireEvent, out Exception deferredException)
{
    deferredException = (Exception) null;
    if (row.tempRecord != proposedRecord)
    {
    if (!this.inDataLoad)
    {
        row.CheckInTable();
        this.CheckNotModifying(row);
    }
    if (proposedRecord == row.newRecord)
    {
        if (!isInMerge)
        return;
        this.RaiseRowChanged((DataRowChangeEventArgs) null, row, action);
        return;
    }
    else
        row.tempRecord = proposedRecord;
    }
    DataRowChangeEventArgs args = (DataRowChangeEventArgs) null;
    try
    {
    row._action = action;
    args = this.RaiseRowChanging((DataRowChangeEventArgs) null, row, action, fireEvent);
    }
    catch
    {
    row.tempRecord = -1;
    throw;
    }
    finally
    {
    row._action = DataRowAction.Nothing;
    }
    row.tempRecord = -1;
    int record = row.newRecord;
    int num = proposedRecord != -1 ? proposedRecord : (row.RowState != DataRowState.Unchanged ? row.oldRecord : -1);
    if (action == DataRowAction.Add)
    {
    if (position == -1)
        this.Rows.ArrayAdd(row);
    else
        this.Rows.ArrayInsert(row, position);
    }
    List<DataRow> cachedRows = (List<DataRow>) null;
    if ((action == DataRowAction.Delete || action == DataRowAction.Change) && (this.dependentColumns != null && this.dependentColumns.Count > 0))
    {
    cachedRows = new List<DataRow>();
    for (int index = 0; index < this.ParentRelations.Count; ++index)
    {
        DataRelation relation = this.ParentRelations[index];
        if (relation.ChildTable == row.Table)
        cachedRows.InsertRange(cachedRows.Count, (IEnumerable<DataRow>) row.GetParentRows(relation));
    }
    for (int index = 0; index < this.ChildRelations.Count; ++index)
    {
        DataRelation relation = this.ChildRelations[index];
        if (relation.ParentTable == row.Table)
        cachedRows.InsertRange(cachedRows.Count, (IEnumerable<DataRow>) row.GetChildRows(relation));
    }
    }
    if (!suppressEnsurePropertyChanged && !row.HasPropertyChanged && (row.newRecord != proposedRecord && -1 != proposedRecord) && -1 != row.newRecord)
    {
    row.LastChangedColumn = (DataColumn) null;
    row.LastChangedColumn = (DataColumn) null;
    }
    if (this.LiveIndexes.Count != 0)
    {
    if (-1 == record && -1 != proposedRecord && (-1 != row.oldRecord && proposedRecord != row.oldRecord))
        record = row.oldRecord;
    DataViewRowState recordState1 = row.GetRecordState(record);
    DataViewRowState recordState2 = row.GetRecordState(num);
    row.newRecord = proposedRecord;
    if (proposedRecord != -1)
        this.recordManager[proposedRecord] = row;
    DataViewRowState recordState3 = row.GetRecordState(record);
    DataViewRowState recordState4 = row.GetRecordState(num);
    this.RecordStateChanged(record, recordState1, recordState3, num, recordState2, recordState4);
    }
    else
    {
    row.newRecord = proposedRecord;
    if (proposedRecord != -1)
        this.recordManager[proposedRecord] = row;
    }
    row.ResetLastChangedColumn();
    if (-1 != record && record != row.oldRecord && (record != row.tempRecord && record != row.newRecord) && row == this.recordManager[record])
    this.FreeRecord(ref record);
    if (row.RowState == DataRowState.Detached && row.rowID != -1L)
    this.RemoveRow(row, false);
    if (this.dependentColumns != null)
    {
    if (this.dependentColumns.Count > 0)
    {
        try
        {
        this.EvaluateExpressions(row, action, cachedRows);
        }
        catch (Exception ex)
        {
        if (action != DataRowAction.Add)
            throw ex;
        deferredException = ex;
        }
    }
    }
    try
    {
    if (!fireEvent)
        return;
    this.RaiseRowChanged(args, row, action);
    }
    catch (Exception ex)
    {
    if (!ADP.IsCatchableExceptionType(ex))
        throw;
    else
        ExceptionBuilder.TraceExceptionWithoutRethrow(ex);
    }
}

:

DataRowCollection.ArrayAdd(DataRow row)
{
  row.RBTreeNodeId = this.list.Add(row);
}

DataRowCollection.ArrayInsert(DataRow row, int pos)
{
  row.RBTreeNodeId = this.list.Insert(pos, row);
}

this.list DataRowCollection.DataRowTree, RBTree<DataRow>.

private sealed class DataRowTree : RBTree<DataRow>

RBTree<DataRow> RBTreeNodeId , Red-Black!

+3

All Articles