LINQ to SQL отключил обновление объекта из другого контекста данных - PullRequest
4 голосов
/ 07 ноября 2008

http://geekswithblogs.net/michelotti/archive/2007/12/17/117791.aspx

Я использую ASP.NET с C # и пытаюсь использовать linq to sql для обновления контекста данных, как показано в блоге, указанном выше. Я создал поле метки времени в таблице, как указано, и использую следующий метод:

private void updateRecord(TableName updatedRecord)
{
 context db = new context();
 db.TableName.Attach(updatedRecord,true);
 db.SubmitChanges();
}

Мой вопрос заключается в том, должны ли вы назначать поле timeStamp для чего-либо в вашем updatedRecord, прежде чем пытаться вызвать метод Attach для своего контекста данных?

Когда я запускаю этот код, я получаю следующее исключение: System.Data.Linq.ChangeConflictException: Row not found or changed. Я обновляю все поля, включая первичный ключ записи, которую я обновляю, перед передачей объекта этому методу обновления. Во время отладки атрибут TimeStamp объекта отображается как ноль. Я не уверен, должно ли это быть так или нет.

В каждой книге и ресурсе, которые у меня есть, говорится, что это способ сделать это, но ни одна из них не вдавалась в подробности об этом атрибуте TimeStamp.

Я знаю, что это быстро и легко, поэтому, если кто-нибудь знает, пожалуйста, дайте мне знать.

Ответы [ 2 ]

3 голосов
/ 08 ноября 2008

Поскольку вы говорите, что создали поле метки времени в таблице, мне интересно, если в случае, когда этот столбец был добавлен позже, свойства столбца могут быть установлены неправильно. Возможно, вы захотите проверить свойства столбца TimeStamp в конструкторе DBML. Убедитесь, что:

AutoGenerated = true
Auto-Sync = Always
Time Stamp = True
Update Check = Never

Тип данных сервера должен быть rowversion NOT NULL

Если он не настроен на автоматическое создание и синхронизацию всегда, версия строки не будет возвращена из вставки, поскольку вы не изменили ее, когда вставка была завершена. Несмотря на то, что это значение генерируется базой данных, DataContext должен знать об этом, чтобы он мог правильно его обрабатывать.

Кроме того, теперь, когда у вас есть столбец отметки времени, UpdateCheck должен быть установлен на Never для всех остальных столбцов.

1 голос
/ 07 ноября 2008

Если у вас есть столбец метки времени, то для обновления записи (из ванильного объекта): да, я бы ожидал назначить ее. В противном случае вы потеряете возможность использовать временную метку для оптимистической проверки параллелизма.

Идея состоит в том, что вы берете копию отметки времени, когда вы получаете свой (отключенный) объект, затем при обновлении вы можете использовать этот столбец, чтобы убедиться, что никто больше не редактировал строку.

Существует два распространенных сценария:

1: если вы выполняете только кратковременную операцию, сначала извлеките запись из базы данных - внесите изменения в объект и просто в SumbitChanges () [все с одним и тем же контекстом данных]. Data-context будет обрабатывать параллелизм для вас.

2: если вы отключаете объект (например, некоторое время передаёте его клиентскому приложению), то используйте что-то вроде сериализации (объекты LINQ-to-SQL поддерживают DataContractSerializer (опционально; вам нужно включить его)). Так что сериализуйте объект на сервере, передайте его клиенту - клиент вносит изменения в свою копию и передает его обратно. Сервер десериализует его и использует Attach () и SubmitChanges (). Запись в памяти все еще должна иметь временную метку, которую она имела при извлечении из базы данных, поэтому мы можем выполнять оптимистический параллелизм, охватывающий все время, когда запись была отключена.

...