internal void InsertRow(DataRow row, long proposedID, int pos, bool fireEvent)
{
Exception deferredException = null;
if (row == null)
{
throw ExceptionBuilder.ArgumentNull(nameof(row));
}
if (row.Table != this)
{
throw ExceptionBuilder.RowAlreadyInOtherCollection();
}
if (row.rowID != -1)
{
throw ExceptionBuilder.RowAlreadyInTheCollection();
}
row.BeginEdit(); // ensure something's there.
int record = row._tempRecord;
row._tempRecord = -1;
if (proposedID == -1)
{
proposedID = _nextRowID;
}
bool rollbackOnException;
if (rollbackOnException = (_nextRowID <= proposedID))
{
_nextRowID = checked(proposedID + 1);
}
try
{
try
{
row.rowID = proposedID;
// this method may cause DataView.OnListChanged in which another row may be added
SetNewRecordWorker(row, record, DataRowAction.Add, false, false, pos, fireEvent, out deferredException); // now we do add the row to collection before OnRowChanged (RaiseRowChanged)
}
catch
{
if (rollbackOnException && (_nextRowID == proposedID + 1))
{
_nextRowID = proposedID;
}
row.rowID = -1;
row._tempRecord = record;
throw;
}
// since expression evaluation occurred in SetNewRecordWorker, there may have been a problem that
// was deferred to this point. If so, throw now since row has already been added.
if (deferredException != null)
throw deferredException;
if (EnforceConstraints && !_inLoad)
{
// if we are evaluating expression, we need to validate constraints
int columnCount = _columnCollection.Count;
for (int i = 0; i < columnCount; ++i)
{
DataColumn column = _columnCollection[i];
if (column.Computed)
{
column.CheckColumnConstraint(row, DataRowAction.Add);
}
}
}
}
finally
{
row.ResetLastChangedColumn();// if expression is evaluated while adding, before return, we want to clear it
}
}