private DataRow LoadRow(object[] values, LoadOption loadOption, Index searchIndex)
{
int recordNo;
DataRow dataRow = null;
if (searchIndex != null)
{
int[] primaryKeyIndex = Array.Empty<int>();
if (_primaryKey != null)
{
// we do check above for PK, but in case if someone else gives us some index unrelated to PK
primaryKeyIndex = new int[_primaryKey.ColumnsReference.Length];
for (int i = 0; i < _primaryKey.ColumnsReference.Length; i++)
{
primaryKeyIndex[i] = _primaryKey.ColumnsReference[i].Ordinal;
}
}
object[] keys = new object[primaryKeyIndex.Length];
for (int i = 0; i < primaryKeyIndex.Length; i++)
{
keys[i] = values[primaryKeyIndex[i]];
}
Range result = searchIndex.FindRecords(keys);
if (!result.IsNull)
{
int deletedRowUpsertCount = 0;
for (int i = result.Min; i <= result.Max; i++)
{
int resultRecord = searchIndex.GetRecord(i);
dataRow = _recordManager[resultRecord];
recordNo = NewRecordFromArray(values);
// values array is being reused by DataAdapter, do not modify the values array
for (int count = 0; count < values.Length; count++)
{
if (null == values[count])
{
_columnCollection[count].Copy(resultRecord, recordNo);
}
}
for (int count = values.Length; count < _columnCollection.Count; count++)
{
_columnCollection[count].Copy(resultRecord, recordNo); // if there are missing values
}
if (loadOption != LoadOption.Upsert || dataRow.RowState != DataRowState.Deleted)
{
SetDataRowWithLoadOption(dataRow, recordNo, loadOption, true);
}
else
{
deletedRowUpsertCount++;
}
}
if (0 == deletedRowUpsertCount)
{
return dataRow;
}
}
}
recordNo = NewRecordFromArray(values);
dataRow = NewRow(recordNo);
// fire rowChanging event here
DataRowAction action;
DataRowChangeEventArgs drcevent = null;
switch (loadOption)
{
case LoadOption.OverwriteChanges:
case LoadOption.PreserveChanges:
action = DataRowAction.ChangeCurrentAndOriginal;
break;
case LoadOption.Upsert:
action = DataRowAction.Add;
break;
default:
throw ExceptionBuilder.ArgumentOutOfRange(nameof(LoadOption));
}
drcevent = RaiseRowChanging(null, dataRow, action);
InsertRow(dataRow, -1, -1, false);
switch (loadOption)
{
case LoadOption.OverwriteChanges:
case LoadOption.PreserveChanges:
SetOldRecord(dataRow, recordNo);
break;
case LoadOption.Upsert:
break;
default:
throw ExceptionBuilder.ArgumentOutOfRange(nameof(LoadOption));
}
RaiseRowChanged(drcevent, dataRow, action);
return dataRow;
}