+ if (_table == null || parentRow.Table == null || RowState == DataRowState.Detached)
+ throw new RowNotInTableException("This row has been removed from a table and does not have any data. BeginEdit() will allow creation of new data in this row.");
+
+ if (parentRow != null && _table.DataSet != parentRow.Table.DataSet)
+ throw new ArgumentException();
+
+ BeginEdit();
+ if (relation == null)
+ {
+ foreach (DataRelation parentRel in _table.ParentRelations)
+ {
+ DataColumn[] childCols = parentRel.ChildKeyConstraint.Columns;
+ DataColumn[] parentCols = parentRel.ChildKeyConstraint.RelatedColumns;
+
+ for (int i = 0; i < parentCols.Length; i++)
+ {
+ if (parentRow == null)
+ this[childCols[i].Ordinal] = DBNull.Value;
+ else
+ this[childCols[i].Ordinal] = parentRow[parentCols[i]];
+ }
+
+ }
+ }
+ else
+ {
+ DataColumn[] childCols = relation.ChildKeyConstraint.Columns;
+ DataColumn[] parentCols = relation.ChildKeyConstraint.RelatedColumns;
+
+ for (int i = 0; i < parentCols.Length; i++)
+ {
+ if (parentRow == null)
+ this[childCols[i].Ordinal] = DBNull.Value;
+ else
+ this[childCols[i].Ordinal] = parentRow[parentCols[i]];
+ }
+ }
+ EndEdit();
+ }
+
+ //Copy all values of this DataaRow to the row parameter.
+ internal void CopyValuesToRow(DataRow row)
+ {
+
+ if (row == null)
+ throw new ArgumentNullException("row");
+ if (row == this)
+ throw new ArgumentException("'row' is the same as this object");
+
+ DataColumnCollection columns = Table.Columns;
+
+ for(int i = 0; i < columns.Count; i++){
+
+ string columnName = columns[i].ColumnName;
+ DataColumn column = row.Table.Columns[columnName];
+ //if a column with the same name exists in both rows copy the values
+ if(column != null) {
+ int index = column.Ordinal;
+ if (HasVersion(DataRowVersion.Original))
+ {
+ if (row.original == null)
+ row.original = new object[row.Table.Columns.Count];
+ row.original[index] = row.SetColumnValue(original[i], column, index);
+ }
+ if (HasVersion(DataRowVersion.Current))
+ {
+ if (row.current == null)
+ row.current = new object[row.Table.Columns.Count];
+ row.current[index] = row.SetColumnValue(current[i], column, index);
+ }
+ if (HasVersion(DataRowVersion.Proposed))
+ {
+ if (row.proposed == null)
+ row.proposed = new object[row.Table.Columns.Count];
+ row.proposed[index] = row.SetColumnValue(proposed[i], column, index);
+ }
+
+ //Saving the current value as the column value
+ row[index] = row.current[index];
+
+ }
+ }
+
+ row.rowState = RowState;
+ row.RowError = RowError;
+ row.columnErrors = columnErrors;
+ }
+
+
+ private void CollectionChanged(object sender, System.ComponentModel.CollectionChangeEventArgs args)
+ {
+ // if a column is added we hava to add an additional value the
+ // the priginal, current and propoed arrays.
+ // this scenario can happened in merge operation.
+
+ if (args.Action == System.ComponentModel.CollectionChangeAction.Add)
+ {
+ object[] tmp;
+ int index = this.Table.Columns.Count - 1;
+ if (current != null)
+ {
+ tmp = new object [index + 1];
+ Array.Copy (current, tmp, current.Length);
+ tmp[tmp.Length - 1] = SetColumnValue(null, this.Table.Columns[index], index);
+ current = tmp;
+ }
+ if (proposed != null)
+ {
+ tmp = new object [index + 1];
+ Array.Copy (proposed, tmp, proposed.Length);
+ tmp[tmp.Length - 1] = SetColumnValue(null, this.Table.Columns[index], index);
+ proposed = tmp;
+ }
+ if(original != null)
+ {
+ tmp = new object [index + 1];
+ Array.Copy (original, tmp, original.Length);
+ tmp[tmp.Length - 1] = SetColumnValue(null, this.Table.Columns[index], index);
+ original = tmp;
+ }
+
+ }
+ }
+
+ internal void onColumnRemoved(int columnIndex)
+ {
+ // when column removed we have to compress row values in the way
+ // they will correspond to new column ordinals
+
+ object[] tmp;
+ if (current != null)
+ {
+ tmp = new object[current.Length - 1];
+ // copy values before removed column
+ if (columnIndex > 0)
+ Array.Copy (current, 0, tmp, 0, columnIndex);
+ // copy values after removed column
+ if(columnIndex < current.Length - 1)
+ Array.Copy(current, columnIndex + 1, tmp, columnIndex, current.Length - 1 - columnIndex);
+
+ current = tmp;
+ }
+ if (proposed != null)
+ {
+ tmp = new object[proposed.Length - 1];
+ // copy values before removed column
+ if (columnIndex > 0)
+ Array.Copy (proposed, 0, tmp, 0, columnIndex);
+ // copy values after removed column
+ if(columnIndex < proposed.Length - 1)
+ Array.Copy(proposed, columnIndex + 1, tmp, columnIndex, proposed.Length - 1 - columnIndex);
+
+ proposed = tmp;
+ }
+ if (original != null)
+ {
+ tmp = new object[original.Length - 1];
+ // copy values before removed column
+ if (columnIndex > 0)
+ Array.Copy (original, 0, tmp, 0, columnIndex);
+ // copy values after removed column
+ if(columnIndex < original.Length - 1)
+ Array.Copy(original, columnIndex + 1, tmp, columnIndex, original.Length - 1 - columnIndex);
+
+ original = tmp;
+ }