private void SetDataRowWithLoadOption (DataRow dataRow, int recordNo, LoadOption loadOption, bool checkReadOnly) {
bool hasError = false;
if (checkReadOnly) {
foreach(DataColumn dc in this.Columns) {
if (dc.ReadOnly && !dc.Computed) {
switch(loadOption) {
case LoadOption.OverwriteChanges:
if ((dataRow[dc, DataRowVersion.Current] != dc[recordNo]) ||(dataRow[dc, DataRowVersion.Original] != dc[recordNo]))
hasError = true;
break;
case LoadOption.Upsert:
if (dataRow[dc, DataRowVersion.Current] != dc[recordNo])
hasError = true;
break;
case LoadOption.PreserveChanges:
if (dataRow[dc, DataRowVersion.Original] != dc[recordNo])
hasError = true;
break;
}
}
}
} // No Event should be fired in SenNewRecord and SetOldRecord
// fire rowChanging event here
DataRowChangeEventArgs drcevent = null;
DataRowAction action = DataRowAction.Nothing;
int cacheTempRecord = dataRow.tempRecord;
dataRow.tempRecord = recordNo;
switch(loadOption) {
case LoadOption.OverwriteChanges:
action = DataRowAction.ChangeCurrentAndOriginal;
break;
case LoadOption.Upsert:
switch(dataRow.RowState) {
case DataRowState.Unchanged:
// let see if the incomming value has the same values as existing row, so compare records
foreach(DataColumn dc in dataRow.Table.Columns) {
if (0 != dc.Compare(dataRow.newRecord, recordNo)) {
action = DataRowAction.Change;
break;
}
}
break;
case DataRowState.Deleted:
Debug.Assert(false, "LoadOption.Upsert with deleted row, should not be here");
break;
default :
action = DataRowAction.Change;
break;
}
break;
case LoadOption.PreserveChanges:
switch(dataRow.RowState) {
case DataRowState.Unchanged:
action = DataRowAction.ChangeCurrentAndOriginal;
break;
default:
action = DataRowAction.ChangeOriginal;
break;
}
break;
default:
throw ExceptionBuilder.ArgumentOutOfRange("LoadOption");
}
try {
drcevent = RaiseRowChanging(null, dataRow, action);
if (action == DataRowAction.Nothing) { // RaiseRowChanging does not fire for DataRowAction.Nothing
dataRow.inChangingEvent = true;
try {
drcevent = OnRowChanging(drcevent, dataRow, action);
}
finally {
dataRow.inChangingEvent = false;
}
}
}
finally {
Debug.Assert(dataRow.tempRecord == recordNo, "tempRecord has been changed in event handler");
if (DataRowState.Detached == dataRow.RowState) {
// 'row.Table.Remove(row);'
if (-1 != cacheTempRecord) {
FreeRecord(ref cacheTempRecord);
}
}
else {
if (dataRow.tempRecord != recordNo) {
// 'row.EndEdit(); row.BeginEdit(); '
if (-1 != cacheTempRecord) {
FreeRecord(ref cacheTempRecord);
}
if (-1 != recordNo) {
FreeRecord(ref recordNo);
}
recordNo = dataRow.tempRecord;
}
else {
dataRow.tempRecord = cacheTempRecord;
}
}
}
if (dataRow.tempRecord != -1) {
dataRow.CancelEdit();
}
switch(loadOption) {
case LoadOption.OverwriteChanges:
this.SetNewRecord(dataRow, recordNo, DataRowAction.Change, false, false);
this.SetOldRecord(dataRow, recordNo);
break;
case LoadOption.Upsert:
if (dataRow.RowState == DataRowState.Unchanged) {
this.SetNewRecord(dataRow, recordNo, DataRowAction.Change, false, false);
if (!dataRow.HasChanges()) {
this.SetOldRecord(dataRow, recordNo);
}
}
else {
if (dataRow.RowState == DataRowState.Deleted)
dataRow.RejectChanges();
this.SetNewRecord(dataRow, recordNo, DataRowAction.Change, false, false);
}
break;
case LoadOption.PreserveChanges:
if (dataRow.RowState == DataRowState.Unchanged) {
// SQLBU 500706: DataTable internal index is corrupted: '8'
// if ListChanged event deletes dataRow
this.SetOldRecord(dataRow, recordNo); // do not fire event
this.SetNewRecord(dataRow, recordNo, DataRowAction.Change, false, false);
}
else { // if modified/ added / deleted we want this operation to fire event (just for LoadOption.PreserveCurrentValues)
this.SetOldRecord(dataRow, recordNo);
}
break;
default:
throw ExceptionBuilder.ArgumentOutOfRange("LoadOption");
}
if (hasError) {
string error = Res.GetString(Res.Load_ReadOnlyDataModified);
if (dataRow.RowError.Length == 0) { // WebData 112272, append the row error
dataRow.RowError = error;
}
else {
dataRow.RowError += " ]:[ " + error ;
}
foreach(DataColumn dc in this.Columns) {
if (dc.ReadOnly && !dc.Computed)
dataRow.SetColumnError(dc, error);
}
}
drcevent = RaiseRowChanged(drcevent, dataRow, action);
if (action == DataRowAction.Nothing) { // RaiseRowChanged does not fire for DataRowAction.Nothing
dataRow.inChangingEvent = true;
try {
OnRowChanged(drcevent, dataRow, action);
}
finally {
dataRow.inChangingEvent = false;
}
}
}