Одно из решений заключается в том, чтобы при сохранении клиент предоставлял как первоначально прочитанные, так и обновленные значения. Тогда вам не нужна копия исходных значений в сеансе.
DataSets имеют встроенную возможность хранить обе версии (DataRowVersion.Original и DataRowVersion.Current), но для этого вам потребуется собственный метод (например, operationContract:
SaveMyData(MyType original, MyType updated);
Затем вы можете сохранить в базе данных таким образом:
UPDATE MyTable
SET Col1 = @NewCol1, Col2 = @NewCol2, ...
WHERE Col1 = @OldCol1, Col2 = @OldCol2, ...
IF @@ROWCOUNT = 0 ... update failed ...
Кроме того, в вашей таблице может быть столбец TIMESTAMP / ROWVERSION. Вы обращаетесь к клиенту и проверяете его при обновлении:
UPDATE MyTable
SET Col1 = @NewCol1, Col2 = @NewCol2, ...
WHERE PKCol = @PK AND TimeStampCol = @OldTimeStamp
IF @@ROWCOUNT = 0 ... update failed ...
Вы, конечно, полагаетесь на то, что клиент правильно вернет исходные значения / оригинальную метку времени при сохранении. Но это не проблема безопасности - злонамеренный клиент не может нанести больше ущерба, чем он мог бы с вашим решением на основе сеанса.