internal void MergeRows(DataRow[] rows)
{
DataTable src = null;
DataTable dst = null;
DataKey key = default(DataKey);
Index ndxSearch = null;
bool fEnforce = _dataSet.EnforceConstraints;
_dataSet.EnforceConstraints = false;
for (int i = 0; i < rows.Length; i++)
{
DataRow row = rows[i];
if (row == null)
{
throw ExceptionBuilder.ArgumentNull($"{nameof(rows)}[{i}]");
}
if (row.Table == null)
{
throw ExceptionBuilder.ArgumentNull($"{nameof(rows)}[{i}].{nameof(DataRow.Table)}");
}
//somebody is doing an 'automerge'
if (row.Table.DataSet == _dataSet)
{
continue;
}
if (src != row.Table)
{ // row.Table changed from prev. row.
src = row.Table;
dst = MergeSchema(row.Table);
if (dst == null)
{
Debug.Assert(MissingSchemaAction.Ignore == _missingSchemaAction, "MergeSchema failed");
_dataSet.EnforceConstraints = fEnforce;
return;
}
if (dst._primaryKey != null)
{
key = GetSrcKey(src, dst);
}
if (key.HasValue)
{
// Getting our own copy instead. ndxSearch = dst.primaryKey.Key.GetSortIndex();
// IMO, Better would be to reuse index
// ndxSearch = dst.primaryKey.Key.GetSortIndex(DataViewRowState.OriginalRows | DataViewRowState.Added );
if (null != ndxSearch)
{
ndxSearch.RemoveRef();
ndxSearch = null;
}
ndxSearch = new Index(dst, dst._primaryKey.Key.GetIndexDesc(), DataViewRowState.OriginalRows | DataViewRowState.Added, null);
ndxSearch.AddRef(); // need to addref twice, otherwise it will be collected
ndxSearch.AddRef(); // in past first adref was done in const
}
}
if (row._newRecord == -1 && row._oldRecord == -1)
{
continue;
}
DataRow targetRow = null;
if (0 < dst.Rows.Count && ndxSearch != null)
{
targetRow = dst.FindMergeTarget(row, key, ndxSearch);
}
targetRow = dst.MergeRow(row, targetRow, _preserveChanges, ndxSearch);
if (targetRow.Table._dependentColumns != null && targetRow.Table._dependentColumns.Count > 0)
{
targetRow.Table.EvaluateExpressions(targetRow, DataRowAction.Change, null);
}
}
if (null != ndxSearch)
{
ndxSearch.RemoveRef();
ndxSearch = null;
}
_dataSet.EnforceConstraints = fEnforce;
}