System.Data.Linq.ChangeConflictException: строка не найдена или изменена - PullRequest
59 голосов
/ 30 апреля 2009

Я пытаюсь удалить выбранную строку сетки, используя LINQ (Нет LinqDataSource).

При изменении выбора привязка подробного просмотра изменяется также. Я могу добавить новую запись в базу данных, но когда я добавил это Код для кнопки удаления внутри панели обновления, я получил исключение:

try
{           
    var query = from i in db.QuestionModules 
                where i.QuestionModuleID == QuestionModuleID 
                select i;

    QuestionModule o = query.First();
    db.QuestionModules.DeleteOnSubmit(o);
    db.SubmitChanges();
}

Это исключение, которое я получаю:

System.Data.Linq.ChangeConflictException: Row not found or changed. at
System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode
failureMode) at
System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges() 

У меня была эта проблема около недели, и независимо от того, что я делаю, это все еще там, и запись не удаляется.

Есть идеи, что делать?

Ответы [ 19 ]

69 голосов
/ 06 июля 2009

ОК - похоже, что (по крайней мере, в моем случае) ответ был для установки все свойства UpdateCheck столбца без первичного ключа на Никогда в файле DBML. Это немедленно решило проблему "Строка не найдена или изменена".

Учитывая слухи о том, что Microsoft не согласна с Linq-To-Sql в пользу Entity Framework, возникает вопрос: будут ли исправлены ошибки такого рода?

51 голосов
/ 29 мая 2011

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

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

15 голосов
/ 06 июля 2009

У меня та же проблема, и я наткнулся на этот блог , который в основном утверждает, что у Linq-To-Sql есть проблема в его оптимистическом параллелизме, где:

  1. Используются поля даты и времени высокой точности. Решение состоит в том, чтобы установить UpdateCheck никогда для этого столбца ваш файл DBML
  2. Столбцы GridView, которые установлены как невидимые, получают доступ к свойству объекта данных (эта вторая причина не имеет смысла, но, похоже, в этом блоге все в моде).

Я еще не пробовал эти решения, но отправлю сюда, как только у меня будет.

14 голосов
/ 04 марта 2013

Я обошел эту проблему, убедившись, что обновляю свой объект непосредственно перед его обновлением. Я делаю это с опцией KeepChanges.

    db.Refresh(System.Data.Linq.RefreshMode.KeepChanges, employee);
13 голосов
/ 02 ноября 2010

Проблема также может заключаться в том, что определение таблицы DBML не соответствует статусу определения базы данных. Я просто удалил модель DBML и снова вставил ее из базы данных, и она сработала.

Надеюсь, это кому-нибудь поможет.

6 голосов
/ 09 сентября 2010

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

Еще одна мысль: я полагаю, что пометка политики UpdateCheck столбца как «Никогда» означает, что она не используется в качестве основы для оптимистичной проверки совпадений. Это будет означать, что два пользователя могут записывать в данную строку с разными данными в любом таком столбце, и конфликты не будут обнаружены ... это означает, что последний пользователь, отправивший строку, перезапишет значения, представленные предыдущими пользователями. Из различных онлайн-чтений я понял, что одним из частичных решений этого является использование метода Refresh непосредственно перед отправкой для синхронизации любых изменений. Конечно, без пессимистической блокировки строки нет гарантии, что строка все равно не будет изменена между Refresh и Submit, но в большинстве сценариев с большими базами данных это будет редко.

Обновление: при дальнейшем рассмотрении я думаю, что обнаружил сценарий, который может повлиять на других, поэтому я решил поделиться им на всякий случай. Оказывается, что, по крайней мере, часть проблем, с которыми я столкнулся с SQL LINQ, связана с триггерами. Похоже, что если вы отправляете строку, используя SQL LINQ, и у вашего администратора есть триггеры, предназначенные для записи информации в некоторые столбцы в этой строке, то модель SQL LINQ по умолчанию будет «Всегда» определять, что строка была изменена с момента вашей последней записи в нее. , Я отправлял частично заполненные строки, и триггеры нашего администратора баз данных заполняют некоторые столбцы, поэтому, когда я попытался дополнительно изменить строку в нашем коде, он обнаружил конфликт изменений, основанный на столбцах, заполненных триггером. Сейчас я изучаю лучший способ справиться с этим, но изменение этих полей, заполненных триггерами, на использование политики UpdateCheck «Когда изменено» или «Никогда» сработало для меня. Надеюсь, это поможет.

3 голосов
/ 01 мая 2015

Это просто случай несоответствующих определений столбцов. Просто удалите таблицу из .dbml и заново добавьте. Обязательно измените auto generate value property = true для столбцов с автоматически сгенерированными данными, таких как первичные ключи или столбцы даты и времени.

2 голосов
/ 02 ноября 2010

У меня было похожее changeconflictexception / "Строка не найдена или изменена" при обновлении строки. Решил это путем повторного добавления таблиц в dbml.

1 голос
/ 26 июня 2014

Проблема, с которой я столкнулся, заключалась в том, что у меня был тип DateTime в .net Framework, но поле нашей базы данных имело тип DateTime2, который является типом данных с более высокой точностью. Поэтому, когда мы будем отправлять изменения, поля даты объекта и БД были отключены всего на несколько наносекунд, что приведет к ошибке параллелизма. Это произошло, когда мы перешли на более новую версию MSSQL, и она преобразовала наши поля DateTime в DateTime2.

Итак, в нашем коде, где мы имели:

    Obj.DateUpdated = DateTime.Now()

Мы изменили его на:

    Obj.DateUpdated = DateTime.Parse(DateTime.Now.ToString())

Поэтому проверьте типы данных, особенно поля даты, если вы получите эту ошибку после обновления и / или миграции.

1 голос
/ 17 февраля 2010

Убедитесь, что в соответствующей таблице нет столбцов, содержащих значения null (т. Е. Обновляемую таблицу).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...