Я использую Entity Framework для заполнения элемента управления сеткой. Иногда, когда я делаю обновления, я получаю следующую ошибку:
Оператор хранения, обновления или удаления затронул неожиданное количество строк (0). Объекты могут быть изменены или удалены с момента загрузки объектов. Обновите записи ObjectStateManager.
Я не могу понять, как воспроизвести это. Но это может быть связано с тем, насколько близко я делаю обновления. Кто-нибудь видел это или кто-нибудь знает, к чему относится сообщение об ошибке?
Изменить: К сожалению, я больше не могу воспроизвести проблему, с которой я столкнулся здесь, потому что я отошел от этого проекта и не помню, нашел ли я в итоге решение, исправил ли его другой разработчик, или я обошел его. Поэтому я не могу принять никаких ответов.
источник
Request.Uri
фактический URL запроса. В моем случае у меня была некоторая логика отслеживания, которая поражала мой сайт и излишне загружала контекст из БД (и иногда обновляла его тоже). Таким образом, на реальной странице, которую я отлаживал, были растоптаны данные с помощью глупой логики кода отслеживания.Ответы:
Это побочный эффект функции, называемой оптимистичным параллелизмом.
Не уверен на 100%, как включить / выключить его в Entity Framework, но в основном он говорит вам о том, что между моментом, когда вы извлекли данные из базы данных, и когда вы сохранили свои изменения, кто-то другой изменил данные (что означало, что вы пошли чтобы сохранить его, 0 строк были обновлены). В терминах SQL предложение их
update
запросаwhere
содержит исходное значение каждого поля в строке, и, если затронуто 0 строк, он знает, что что-то пошло не так.Идея заключается в том, что вы не перестанете переписывать изменения, о которых ваше приложение не знало, - это, по сути, небольшая мера безопасности, добавляемая .NET для всех ваших обновлений.
Если это не противоречит, то, скорее всего, это происходит в вашей собственной логике (например, вы сами обновляете данные в другом методе между выбором и обновлением), но это может быть просто условием гонки между двумя приложениями.
источник
Я столкнулся с этим, и это было вызвано тем, что поле ID (ключ) сущности не было установлено. Таким образом, когда контекст пошел на сохранение данных, он не смог найти ID = 0. Обязательно поместите точку останова в операторе обновления и убедитесь, что идентификатор сущности установлен.
Из комментария Пола Беллора
источник
Вау, много ответов, но я получил эту ошибку, когда сделал что-то немного другое, о чем не упоминал ни один другой.
Короче говоря, если вы создадите новый объект и скажите EF, что он был изменен с использованием,
EntityState.Modified
то он выдаст эту ошибку, так как он еще не существует в базе данных. Вот мой код:Да, это кажется глупым, но оно возникло потому, что рассматриваемый метод раньше
foo
передавал ему, будучи созданным ранее, теперь он толькоsomeValue
передал ему и создаетfoo
сам.Легко исправить, просто изменить
EntityState.Modified
кEntityState.Added
или изменить , что вся линия:источник
Я столкнулся с той же самой страшной ошибкой ... :) Потом я понял, что забыл установить
@Html.HiddenFor(model => model.UserProfile.UserId)
для первичного ключа обновляемого объекта! Я склонен забывать эту простую, но очень важную вещь!
Кстати:
HiddenFor
это для ASP.NET MVC.источник
UserId
в форме, очень склонной к хакерам ... это должно быть заполнено впоследствии изHttpContext.Current.User.Identity.Name
HiddenFor
файле вам нужно вHttpContext
любом случае, чтобы получить его от ... Я бы вообще не поместил это свойство в форму, что заставило бы меня всегда заполнять его на стороне сервера ...Проверьте, не забыли ли вы атрибут «DataKeyNames» в GridView. это необходимо при изменении данных в GridView
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
источник
Проблема вызвана одной из двух причин:
Concurrency Mode: Fixed
.. и оптимистический параллелизм не позволил сохранить данные. То есть. некоторые изменяли данные строки между временем получения вами данных сервера и сохранением данных вашего сервера.StoreGeneratedPattern = Computed
), и эта строка не существует.источник
Я получил эту же ошибку, потому что часть PK была столбцом datetime, а вставляемая запись использовала DateTime.Now в качестве значения для этого столбца. Платформа сущностей будет вставлять значение с точностью до миллисекунды, а затем искать только что вставленное значение с точностью до миллисекунды. Однако SqlServer округлил значение до второй точности, и, таким образом, объектная структура не смогла найти значение с точностью до миллисекунды.
Решение было обрезать миллисекунды от DateTime.Now перед вставкой.
источник
Date
столбец соDateTime
значениемУ меня возникла та же проблема, и ответ @ webtrifusion помог найти решение.
Моя модель использовала
Bind(Exclude)
атрибут идентификатора сущности, что приводило к тому, что значение идентификатора сущности было нулевым на HttpPost.источник
У меня была та же проблема, я выяснил, что это было вызвано RowVersion, который был нулевым. Убедитесь, что ваш Id и RowVersion не равны NULL .
для получения дополнительной информации обратитесь к этому руководству
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application
источник
Я начал получать эту ошибку после перехода с модели сначала на код сначала. У меня есть несколько потоков, обновляющих базу данных, где некоторые могут обновлять одну и ту же строку. Я не знаю, почему у меня не возникло проблем с использованием model-first, предположим, что он использует другое значение по умолчанию для параллелизма.
Чтобы справиться с этим в одном месте, зная условия, при которых это может произойти, я добавил следующую перегрузку в мой класс DbContext:
Затем вызывается,
SaveChanges(true)
где это применимо.источник
Вам необходимо явно включить BoundField первичного ключа. Если вы не хотите, чтобы пользователь видел первичный ключ, вы должны скрыть его с помощью css:
Где «скрытый» - это класс в css, для которого установлено отображение «нет».
источник
При редактировании включите идентификатор или первичный ключ объекта в качестве скрытого поля в представлении.
т.е.
это решает проблему.
Также, если ваша модель содержит неиспользуемый элемент, включите его и отправьте на контроллер
источник
Я тоже сталкивался с этой ошибкой. Проблема оказалась вызвана триггером на столе, к которому я пытался сохранить. Триггер использовал «INSTEAD OF INSERT», что означает, что 0 строк когда-либо вставлялось в эту таблицу, следовательно, ошибка. К счастью, в некоторых случаях функциональность триггера была неправильной, но я предполагаю, что это может быть допустимой операцией, которая должна каким-то образом обрабатываться в коде. Надеюсь, это поможет кому-нибудь однажды.
источник
SELECT SCOPE_IDENTITY() as MyViewId
Я столкнулся с этой проблемой в таблице, в которой отсутствовал первичный ключ и имел столбец DATETIME (2, 3) (поэтому «первичный ключ» сущности представлял собой комбинацию всех столбцов) ... При выполнении вставки метка времени имела более точное время (2018-03-20 08: 29: 51.8319154), которое было усечено до (2018-03-20 08: 29: 51.832), поэтому поиск по ключевым полям не удался.
источник
У меня тоже была эта ошибка. В некоторых ситуациях сущность может не знать о фактическом контексте базы данных, который вы используете, или модель может отличаться. Для этого установите: EntityState.Modified; в EntityState.Added;
Сделать это:
Это гарантирует, что Организация знает, что вы используете или добавляете штат, с которым вы работаете. На этом этапе все правильные значения модели должны быть установлены. Будьте осторожны, чтобы не потерять какие-либо изменения, которые могли быть сделаны в фоновом режиме.
Надеюсь это поможет.
источник
Моя версия строки была нулевой, поэтому пришлось добавить это к представлению, которое решило мою проблему
источник
Линия
[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
добилась цели в моем случае:источник
Просто убедитесь, что таблица и форма имеют первичный ключ и edmx обновлены.
я обнаружил, что любые ошибки во время обновления обычно были из-за: - Нет первичного ключа в таблице - Нет первичного ключа в представлении / форме редактирования (например
@Html.HiddenFor(m=>m.Id
)источник
У меня такая же проблема. В моем случае я пытался обновить первичный ключ, что не разрешено.
источник
Я получил эту ошибку спорадически при использовании
async
метода. Не произошло, так как я перешел на синхронный метод.Ошибки время от времени:
Работает все время:
источник
Я получил эту ошибку, когда удалял несколько строк в БД (в цикле) и добавлял новые в той же таблице.
Решением для меня было динамическое создание нового контекста в каждой итерации цикла
источник
источник
Это также произойдет, если вы пытаетесь вставить в уникальную ситуацию ограничения, то есть, если у вас может быть только один тип адреса на одного работодателя, и вы пытаетесь вставить секунду того же типа с тем же работодателем, вы получите ту же проблему ,
ИЛИ
Это также может произойти, если все свойства объекта, которые были назначены, им были присвоены те же значения, что и раньше.
источник
Если вы пытаетесь создать сопоставление в своем файле edmx с функцией «Импорт», это может привести к этой ошибке. Просто очистите поля для вставки, обновления и удаления, которые находятся в Mapping Details для данного объекта в вашем edmx, и это должно работать. Надеюсь, я дал понять.
источник
Я получил это исключение при присоединении объекта, который не существует в базе данных. Я предполагал, что объект был загружен из отдельного контекста, но если пользователь впервые зашел на сайт, он был создан с нуля. У нас есть автоинкрементные первичные ключи, поэтому я мог бы заменить
с участием
источник
Ну, у меня есть такая же проблема. Но это было из-за моей собственной ошибки. На самом деле я сохранял объект вместо того, чтобы добавить его. Так что это был конфликт.
источник
Одним из способов решения этой проблемы в среде сервера Sql является использование Sql Profiler, включенного в вашу копию SqlServer, или, если вы используете версию Express, получите бесплатную копию Express Profiler из CodePlex по следующей ссылке:
Экспресс Профилировщик
Используя Sql Profiler, вы можете получить доступ ко всему, что отправляет EF в БД. В моем случае это составило:
Я скопировал вставил это в окно запроса в Sql Server и выполнил его. Конечно, несмотря на то, что он выполнялся, на 0 записей повлиял этот запрос, поэтому EF вернула ошибку.
В моем случае проблема была вызвана CategoryID.
Не было идентификатора категории, идентифицированного идентификатором EF, отправленным в базу данных, следовательно, затронуто 0 записей.
Это была не ошибка EF, а скорее глючная нуль-слияние "??" утверждение в контроллере представления, который отправлял ерунду на уровень данных.
источник
Ни один из приведенных выше ответов не вполне охватил мою ситуацию и ее решение.
Код, в котором была выдана ошибка в контроллере MVC5:
Я получил это исключение, когда я сохранял объект из представления редактирования. Это вызвано тем, что когда я вернулся, чтобы сохранить его, я изменил свойства, которые сформировали первичный ключ объекта. Таким образом, установка его состояния на Modified не имеет никакого смысла для EF - это была новая запись, а не ранее сохраненная.
Вы можете решить это, либо A) изменив вызов save для добавления объекта, либо B) просто не изменив первичный ключ при редактировании. Я сделал б).
источник
Когда принятый ответ сказал: « Это не приведет к перезаписи изменения, о котором ваше приложение не знает », я скептически отнесся к тому, что мой объект был недавно создан. Но затем выясняется, что
INSTEAD OF UPDATE, INSERT- TRIGGER
к таблице была прикреплена таблица, которая обновляла вычисляемый столбец этой же таблицы.Как только я изменил это на
AFTER INSERT, UPDATE
, все работало нормально.источник
Это произошло со мной из-за несоответствия между datetime и datetime2. Странно, он работал нормально до того, как тестер обнаружил проблему. Моя модель Code First включала DateTime как часть первичного ключа:
Созданный столбец является столбцом даты и времени. При вызове SaveChanges EF генерирует следующий SQL:
Поскольку он пытался сопоставить столбец datetime со значением datetime2, он не дал результатов. Единственное решение, о котором я мог подумать, это изменить столбец на datetime2:
источник
datetime
противdatetime2
. По существу, некоторые значения в миллисекундах будут соответствовать друг другу, другие - нет. То же самое случилось со мной, и я тоже переключился наDateTime2
.