Linq строка не найдена или изменена - PullRequest
17 голосов
/ 13 января 2012
Error Message: Row not found or changed.
Stack Trace:
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) 
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) 

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

Я могу исправить эту ошибку следующим образом:

  • my dbml layout
  • Выбор каждого поля в таблице, вызывающего конфликты
  • Щелкните правой кнопкой мыши и установите для свойства Update Check значение Never

Это кажетсяне допускайте появления ошибок такого типа.

Тем не менее, очень трудно помнить о том, чтобы продолжать делать всякий раз, когда я даю шанс dmbl, добавлять новые таблицы и т. д. Есть ли лучший способ решить эту проблему??Я получаю от 50 до 100 таких в день, что плохо для моих посетителей.

Ответы [ 8 ]

50 голосов
/ 25 июня 2013

У меня была та же проблема, и я решил ее, сравнив dbml со структурой db. Одно свойство не было установлено в nullable, и это вызывало проблему.

Итак, проверьте ваш dbml и обнуляемые свойства.

28 голосов
/ 13 января 2012

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

Я не знаю точную природу вашего приложения, но я предполагаю, что вы создаете контекст данных, загружаете запись или списокзаписи, выполняя некоторые операции над ним, затрачивая время и процессорные циклы, а затем в конце пытаясь сохранить измененные данные обратно в базу данных.Может быть, даже загружать экземпляр записи / объекта и сохранять его некоторое время в переменной класса, а затем в конце загрузки страницы или потока или чего-либо другого, пытаясь сохранить обратно все, что изменилось.Проблема в том, что, поскольку LINQ хранит копию этой копии, она должна быть обновлена.Если базовые данные тем временем изменяются, они злятся.

Задайте себе вопрос: что, если вы поместите блокирующую транзакцию в свои данные на все время жизни ваших объектов.Скажите, что все, что вы загрузили, может измениться, никто больше не сможет прикоснуться к нему в течение этого времени.В основном это предположение здесь.Конечно, LINQ немного более оптимистичен в этом отношении, нет смысла блокировать строку или таблицу, если вы никогда не обновляете данные, но вы думаете об этих проблемах.Спросите себя, что могло бы существенно сломаться или замедлиться, если бы вы наложили строгие транзакционные блокировки на ваши объекты, и это, вероятно, укажет вам на код, вызывающий сбой.

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

2 голосов
/ 30 сентября 2016

Это также может произойти, если триггер базы данных изменяет какой-либо столбец в обновляемой строке, даже если вы не обновляете этот конкретный столбец.

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

2 голосов
/ 01 ноября 2012

GetTable (). Attach (newEntity, originalEntity);

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

1 голос
/ 01 апреля 2015

Используя SQL Profiler, я отслеживал транзакции SQL на моем сервере и обнаружил, что на SubmitChanges() переданный оператор UPDATE содержит неправильное значение в предложении WHERE.Это потому, что у меня есть свойство, которое выглядит следующим образом:

class Position{
...
    [Column]
    public int Pieces{
        get{
            this.pieces = this.Transformers.Count;

            return this.pieces;
        }
        set{ this.pieces = value; }
    }
...
}

Поскольку Transformers - это элемент List<Transformers>, представляющий список отношений «один ко многим» с другой таблицей Transformers, явручную нужно заполнить список каждым Transformer, который содержит внешний ключ к моему Position объекту.Если по какой-то причине я этого не сделаю, я получу упомянутую ошибку, поскольку свойство Pieces смещено относительно исходного значения.

Таким образом, оператор SQL на SubmitChanges() будет искать запись WHERE Pieces = somevalue, но фактическое значение Pieces в записи anothervalue.Поэтому в основном LINQ будет думать, что вы тем временем что-то изменили в БД, потому что БД не будет возвращать значение для этого запроса.

Как уже говорилось, одно из решений:

    [Column(UpdateCheck=UpdateCheck.Never)]
    public int Pieces
    {
        get {
            this.pieces= this.Transformers.Count;

            return this.pieces; 
        }
        set { this.pieces= value; }
    }

Конечноэто также может быть легко решено путем установки простой функции получения, такой как

getPieces(){
    return this.Transformers.Count();
}

и «беспристрастного» свойства

class Position{
...
    [Column]
    public int Pieces{
        get{ return this.pieces; }
        set{ this.pieces = value; }
    }
...
}

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

1 голос
/ 30 декабря 2013

Иногда это действительно просто ... Убедитесь, что на столе нет замков. В моем случае пользовательский интерфейс SQL Server Management Studio содержал блокировки, о которых я не знал (не помнил) во время отладки. Разгрузка его очистила эти замки, и все снова заработало.

0 голосов
/ 27 февраля 2017

обновление схемы linq до sql в конструкторе решает проблему в моем случае

0 голосов
/ 01 июля 2014

Я получал эту ошибку на Windows Phone 8. И мне потребовалось некоторое время, чтобы понять, в чем проблема.В основном это было так:

У меня был класс TrackingInformation.1. С сервера я получил обновленную версию.2. Мой TileService обновил дополнительную плитку с ее информацией и (!!) обновил 1 свойство и сохранил его в локальной базе данных на телефоне.3. Я попытался сохранить первый экземпляр объекта снова, и здесь я получил ошибку «строка не найдена или изменена».

Для меня мне просто нужно было удалить 3-ю часть, и она работала нормально (уже сохранено с обновленной версией).Но поскольку одно свойство изменилось, возникло исключение ...

Я не могу дождаться, когда EF7 выйдет на Windows Phone, такая большая головная боль с текущим EF на WP8.

...