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 ]

0 голосов
/ 09 июля 2012

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

0 голосов
/ 29 апреля 2012

У меня была похожая проблема, и хотя удаление и повторное добавление таблицы / класса DBML помогло некоторым пользователям, для меня это было немного по-другому, поскольку я использую WCF с отсоединенной сущностью и ListView на клиенте.

Если я использовал .Attach (сущность), то это не удалось - «Строка не найдена или изменена» Но при использовании .Attach (сущность, оригинал) он работает каждый раз

public void DeleteTask(Task task)
    {
        TwoDooDataContext db = new TwoDooDataContext();
        db.Tasks.Attach(task,GetTaskByID(task.ID));
        db.Tasks.DeleteOnSubmit(task);
        db.SubmitChanges();
    }
0 голосов
/ 07 марта 2012

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

Мы используем пользовательский T4 для нашего dqml Linq to SQL. Мы просто изменили исходные свойства строки get / set для автоматической обрезки и установки нуля.

        get { return _OfficiantNameMiddle.GetValueOrNull(); }
        set 
        {
            value = value.GetValueOrNull();
            if (_OfficiantNameMiddle != value) 
            {
                _IsDirty = true;
                OnOfficiantNameMiddleChanging(value);
                SendPropertyChanging("OfficiantNameMiddle");
                _OfficiantNameMiddle = value;
                SendPropertyChanged("OfficiantNameMiddle");
                OnOfficiantNameMiddleChanged();
            }
        }

У устаревших данных в нашей базе данных было несколько начальных / конечных пробелов, поэтому любая проверка параллельности для этих столбцов не привела к совпадению (сравнивалось усеченное значение со значением необрезанного значения базы данных). Было очень легко профилировать SQL, захватить SQL и начать комментировать элементы в предложении WHERE, пока он не начнет возвращать строку во время проверки параллелизма.

К счастью, в наших таблицах есть поле LastUpdatedOn, которое автоматически устанавливается с помощью OnValidate (System.Data.Linq.ChangeAction).

    partial void OnValidate(System.Data.Linq.ChangeAction action)
    {
        if (action == System.Data.Linq.ChangeAction.Insert)
        {
            CreatedBy = CurrentUserID;
            CreatedOn = DateTime.Now;
            LastUpdatedBy = CreatedBy;
            LastUpdatedOn = CreatedOn;
        }
        else if (action == System.Data.Linq.ChangeAction.Update)
        {
            LastUpdatedBy = CurrentUserID;
            LastUpdatedOn = DateTime.Now;
        }
    }

Чтобы обойти проблему, мы просто устанавливаем проверку параллелизма Никогда во всех столбцах, кроме столбцов первичного ключа и столбца LastUpdatedOn. Это сработало для нас.

0 голосов
/ 04 октября 2011

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

e.Keys["ColumnOne"] ="new value"
e.Keys["ColumnTwo"] ="new value"

Все это было сделано в рамках события GridView_RowUpdating.

0 голосов
/ 11 ноября 2009

Under:

QuestionModule o = query.First();

Вы должны добавить следующую команду:

db.QuestionModule.Attach(o);
0 голосов
/ 14 февраля 2017

Как указано @ dherrin79, это может быть вызвано из-за разницы в точности между базой данных и кодом. Для меня проблема заключалась в том, что столбец базы данных должен был быть десятичным (10,2), но он был создан как десятичный (18,0). Это было для денежного поля, так что, возможно, я должен был использовать тип столбца денег.

Итак, я сэкономил сумму в долларах, например, 3,14 доллара, но десятичная дробь была убрана. Это привело к изменению значения базы данных и его несоответствию значению в C #.

Надеюсь, это поможет.

0 голосов
/ 22 февраля 2010

Мне удалось решить эту проблему, выполнив databind () для gridview и источника данных во время обратной передачи панели обновления.

    protected void UpdatePanel1_Load(object sender, EventArgs e)
    {
        GridView1.DataBind();
        LinqDataSource1.DataBind();
    }

Я обновляю панель обновления каждый раз, когда изменяется мой индекс выбора, и он смог разрешить конфликты.

Надеюсь, это поможет.

0 голосов
/ 08 октября 2018

Для нас проблема началась, когда мы переключились на DateTime2 на стороне SQL Server. Просто пометка полей с помощью столбца (DbType = "DateTime2") не помогла. Итак, произошло то, что первоначально на стороне базы данных мы объявили наши столбцы как DateTime2 (3) как «обратно совместимые» со старым типом DateTime, и все казалось работающим нормально, пока мы не заметили, что когда мы используем SQL-2-Linq, мы получите исключение «Строка не найдена или изменена» в обновлениях этих полей даты. Короче говоря, решением было сделать 2 вещи:

  1. Пометьте столбцы с помощью [Column (DbType = "DateTime2 (3)", CanBeNull = false)], чтобы соответствовать объявлению базы данных. И
  2. Обрезать лишние прецизионные цифры из свойств в установщиках следующим образом:

[Column(DbType = "DateTime2(3)", CanBeNull = false)] public DateTime ModifiedAt { get => _modifiedAt; set => _modifiedAt = value.AddTicks(-(value.Ticks % TimeSpan.TicksPerMillisecond)); }

0 голосов
/ 11 августа 2011

Также - если вы вызываете метод выбора для linqdatasource и устанавливаете e.result вручную, убедитесь, что вы также включили любые значения посторонних ключей.

У меня больше ничего не получалось, кроме этого.

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