Entity Framework: «Оператор store update, insert или delete затронул неожиданное количество строк (0)». [Закрыто]

266

Я использую Entity Framework для заполнения элемента управления сеткой. Иногда, когда я делаю обновления, я получаю следующую ошибку:

Заявление об обновлении, вставке или удалении повлияло на неожиданное количество строк (0). Объекты могут быть изменены или удалены, поскольку объекты загружены. Обновить записи ObjectStateManager.

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

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

  • 0
    Я получил эту ошибку с введением политики безопасности на уровне строк в SQL Server, которая позволяла обновлять строку в состояние, которое не может быть прочитано (эксклюзивный предикат FILTER с разрешающим предикатом BLOCK) . EntityFramework требует, чтобы обновленная строка читалась обратно после обновления, в противном случае предполагается, что это была ошибка параллелизма (по крайней мере, при использовании оптимистичного параллелизма).
  • 0
    Проблема может быть в неправильной области видимости для вашего DBContext stackoverflow.com/questions/49154250/… (этот пример для удостоверения ASPNET, но применяется для любого контекста)
Показать ещё 2 комментария
Теги:
razor
entity-framework
asp.net-mvc

42 ответа

155
Лучший ответ

Это побочный эффект функции, называемой оптимистичной concurrency.

Не 100% уверен, как включить или отключить его в Entity Framework, но в основном то, что он говорит вам, заключается в том, что между вами, когда вы извлекаете данные из базы данных, и когда вы сохранили изменения, кто-то другой изменил данные (что означало когда вы пошли, чтобы сохранить его, 0 строк действительно обновились). В терминах SQL их предложение update query where содержит исходное значение каждого поля в строке, и если 0 строк затронуты, он знает, что что-то пошло не так.

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

Если это согласовано, вероятность того, что это происходит в вашей собственной логике (EG: вы фактически обновляете данные самостоятельно в другом методе между выбором и обновлением), но это может быть просто условие гонки между двумя приложениями.

  • 31
    Это происходит в однопользовательской среде (на моей машине разработчика), поэтому я не думаю, что это может быть условием гонки. Я привязываюсь к пользовательскому элементу управления сеткой с помощью EntityDataSource, поэтому я не уверен, что именно происходит за кулисами, но у меня нет собственного дополнительного кода, который модифицирует таблицы. Есть ли способ изменить этот параметр параллелизма?
  • 2
    Я думаю, что вы можете сделать это для каждой колонки в вашей модели сущности (она находится в окне свойств), но дело в том, что вы просто не сможете увидеть ошибку и ничего не обновите. Можете ли вы просмотреть команды SQL, идущие в вашу базу данных (например, SQL Server Profiler для MSSQL)? Таким образом, вы сможете увидеть, какое обновление оно сгенерировало, и понять, почему это обновление не влияет на строки.
Показать ещё 6 комментариев
323

Я столкнулся с этим, и это было вызвано тем, что поле идентификатора объекта (ключа) не было установлено. Таким образом, когда контекст пошел на сохранение данных, он не смог найти идентификатор = 0. Обязательно поместите точку останова в свой оператор обновления и убедитесь, что идентификатор объекта был установлен.

От комментария Пола Беллоры

У меня была эта точная проблема, вызванная забыванием включить скрытый идентификатор ввод на странице редактирования .cshtml

  • 69
    +1 Спасибо за добавление этого ответа - у меня была именно эта проблема, вызванная тем, что я забыл включить скрытый ввод идентификатора на страницу редактирования .cshtml.
  • 3
    +1 У меня была такая же проблема, и это помогло найти решение. Оказывается, в моей модели Order было [Bind (Exclude = "OrderID")], что приводило к тому, что значение идентификатора сущности равнялось нулю на HttpPost.
Показать ещё 13 комментариев
76

Ничего себе, много ответов, но я получил эту ошибку, когда сделал что-то немного другое, о чем не упоминал нигде.

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

MyObject foo = new MyObject()
{
    someAttribute = someValue
};

context.Entry(foo).State = EntityState.Modified;
context.SaveChanges();

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

Простое исправление, просто измените EntityState.Modified на EntityState.Added или измените всю эту строку на:

context.MyObject.Add(foo);
  • 1
    Да уж! У меня та же проблема. Ваш ответ решил мою проблему. Спасибо :)
  • 1
    именно так! это был мой случай
Показать ещё 2 комментария
22

Я столкнулся с такой же пугающей ошибкой...:) Тогда я понял, что забыл установить

@Html.HiddenFor(model => model.UserProfile.UserId)

для первичного ключа обновляемого объекта! Я стараюсь забыть простую, но очень важную вещь!

Кстати: HiddenFor для ASP.NET MVC.

  • 3
    Это похоже на недостаток безопасности, чтобы хранить UserId в форме, очень подверженной хакерам ... это должно быть заполнено впоследствии из HttpContext.Current.User.Identity.Name
  • 0
    @SerjSagan вы правы ... но пока вы делаете некоторые проверки на стороне сервера, чтобы подтвердить ID пользователя и текущее имя пользователя, вы можете пойти.
Показать ещё 1 комментарий
16

Проверьте, не забыл ли вы атрибут "DataKeyNames" в GridView. это необходимо при изменении данных в GridView

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx

  • 0
    спасибо ... это отлично сработало
  • 0
    +1. Идеальное и простое решение для меня. Я привязываю GridView к EntityDataSource и не установил это в качестве моего первичного ключа на объекте.
Показать ещё 1 комментарий
13

Проблема вызвана одной из двух вещей: -

  • Вы пытались обновить строку с одним или несколькими свойствами Concurrency Mode: Fixed.., а Оптимистичный Concurrency не позволил сохранить данные. То есть. некоторые изменили данные строки между временем, когда вы получили данные сервера, и когда вы сохранили данные своего сервера.
  • Вы пытались обновить или удалить строку, но строка не существует. Другой пример того, кто-то меняет данные (в этом случае, удаляет) между восстановлением, затем сохраняет ИЛИ вы плоские, пытаясь обновить поле, которое не является идентификатором (т.е. StoreGeneratedPattern = Computed), и эта строка не существует.
  • 1
    Это также может быть вызвано тем, что все свойства объекта, которые были назначены, им были присвоены те же значения, что и раньше.
  • 0
    +1 за 2й. У меня StoreGeneratedPattern = None, меняя на StoreGeneratedPattern = Identity решил проблему. Спасибо
8

У меня была та же проблема, я выяснил, что это было вызвано RowVersion, которая была нулевой. Убедитесь, что Идентификатор и RowVersion не нуль.

для получения дополнительной информации см. этот учебник

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application

  • 0
    версия строки была нулевой в моем случае
  • 0
    В моем случае я случайно удалил поле Id в моем [Bind (Include = properties)]. Добавьте его обратно, и он работал нормально.
8

У меня была такая же проблема, и @webtrifusion ответ помог найти решение.

Моя модель использовала атрибут Bind(Exclude) в идентификаторе объекта, который вызывал значение идентификатора объекта в HttpPost.

namespace OrderUp.Models
{
[Bind(Exclude = "OrderID")]
public class Order
{
    [ScaffoldColumn(false)]
    public int OrderID { get; set; }

    [ScaffoldColumn(false)]
    public System.DateTime OrderDate { get; set; }

    [Required(ErrorMessage = "Name is required")]
    public string Username { get; set; }
    }
}   
  • 0
    Похожая проблема, по соображениям безопасности, у меня есть Bind (include = некоторые поля). ID не было в списке. Также я добавил это как скрытый вход. Должно быть, стерто что-то, сгенерированное MVC, или ID вообще не было. Спасибо за помощь.
7

Во время редактирования включается идентификатор или первичный ключ объекта как скрытое поле в представлении

т

      @Html.HiddenFor(m => m.Id)

который решает проблему.

Кроме того, если ваша модель включает неиспользуемый элемент, включите это и отправьте это на контроллер

6

Вам нужно явно включить BoundField первичного ключа. Если вы не хотите, чтобы пользователь видел первичный ключ, вам нужно скрыть его с помощью css:

    <asp:BoundField DataField="Id_primary_key" ItemStyle-CssClass="hidden" 
HeaderStyle-CssClass="hidden" />

Где "hidden" - это класс в css, для которого установлено значение "none".

  • 0
    хах, вы поняли, что я удалил свое скрытое поле идентификатора в ASP.NET MVC. Спасибо @ Пауло! :)
  • 0
    Это решение сработало для меня. Спасибо, Пауло.
Показать ещё 1 комментарий
5

Я также столкнулся с этой ошибкой. Проблема, которая, как оказалось, была вызвана триггером на таблице, которую я пытался сохранить. В Trigger используется "INSTEAD OF INSERT", что означает, что в эту таблицу вставлены 0 строк, следовательно, ошибка. К счастью, в случае, когда функция триггера была неправильной, но я предполагаю, что это может быть действительная операция, которая должна каким-то образом обрабатываться в коде. Надеюсь, это поможет кому-то в один прекрасный день.

  • 2
    Сущность можно обмануть, поверив, что строки были добавлены путем возврата оператора SELECT (со столбцом первичного ключа) из триггера.
  • 1
    Чтобы расширить комментарий @jahu, мне нужно было получить фактический идентификатор вновь вставленного элемента, который должен быть возвращен из моего триггера, а имя столбца должно соответствовать столбцу идентификаторов таблицы триггера (в моем случае, фактически это представление, так что У меня нет собственной идентичности, но я обманул edmx, заставив поверить в это. Мой триггер делал вставку в отдельную таблицу, поэтому я просто добавил эту последнюю строку в свой триггер: SELECT SCOPE_IDENTITY() as MyViewId
Показать ещё 2 комментария
4

Я получил ту же ошибку, потому что часть PK была столбцом datetime, а вставляемая запись использовала DateTime.Now как значение для этого столбца. Структура Entity будет вставлять значение с точностью до миллисекунды, а затем искать значение, которое он только вставил, также с точностью до миллисекунды. Однако SqlServer округлил значение до второй точности, и, таким образом, инфраструктура сущности не смогла найти значение точности в миллисекундах.

Решением было усечение миллисекунд из DateTime.Now перед вставкой.

  • 2
    У нас была та же проблема, за исключением того, что мы вставляли в столбец Date со значением DateTime
  • 1
    Тоже самое. У нас была запись из хранилища данных, и мы использовали временную метку как часть ключа. Отметка времени в хранилище данных была SQL DateTime, но отметка времени в C # не совпадала. Я изменил тип данных SQL на DateTime2 (7), обновил модель EF, и все было исправлено.
Показать ещё 1 комментарий
4
  @Html.HiddenFor(model => model.RowVersion)

Моя rowversion была нулевой, поэтому пришлось добавить это в представление который решил мою проблему

  • 0
    Не передавал RowVersion из представления в действие редактирования, плюс я забыл сделать привязку модели для RowVersion. В то время, когда вы сохраняете объект в БД, вам нужно, чтобы предыдущее значение RowVersion было отправлено в БД вместе с объектом для проверки параллелизма. Вы делаете глупые ошибки, когда вам нужны вещи быстрее!
4

Просто убедитесь, что таблица и форма имеют первичный ключ и edmx.

я обнаружил, что любые ошибки во время обновления обычно происходили из-за:  - Нет первичного ключа в таблице  - Нет первичного ключа в Редактировании вида/формы (например, @Html.HiddenFor(m=>m.Id)

3

У меня была та же проблема. В моем случае я пытался обновить первичный ключ, который не разрешен.

3

Я получил эту ошибку, когда я удалял некоторые строки в БД (в цикле) и добавлял новые в ту же таблицу.

Решения для меня заключались в том, чтобы динамически создавать новый контекст в каждой итерации цикла

  • 0
    Я должен был сделать то же самое, все еще не уверенный, почему проблема возникла в первую очередь, но это работает.
2

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

Чтобы обрабатывать его в одном месте, зная условия, при которых это могло произойти, я добавил следующую перегрузку в класс DbContext:

using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;

public class MyDbContext: DbContext {
...
        public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) {
            try {
                return SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex) {
                foreach (DbEntityEntry entry in ex.Entries) {
                    if (refreshMode == RefreshMode.ClientWins)
                        entry.OriginalValues.SetValues(entry.GetDatabaseValues());
                    else
                        entry.Reload();
                }
                return SaveChanges();
            }
        }
}

Затем называется SaveChanges(true), где это применимо.

  • 0
    ОК, все остальные жалуются на проблему, показывают, как они могут ее вызвать и т. Д., Но этот ответ имеет крутой ответ. Я использую модель продолжения обновления (здесь нет кнопки сохранения, детка), и получал это при обновлениях сетки, когда поток EF отставал, и решил это. Блестящая работа, мое доброе имя .. ты заставил меня выглядеть как герой - стоя на плече гигантов !!
2

Ну, у меня такая же проблема. Но это было связано с моей собственной ошибкой. Фактически я сохранял объект вместо его добавления. Итак, это был конфликт.

2

Одним из способов отладки этой проблемы в среде Sql Server является использование Sql Profiler, включенного в вашу копию SqlServer, или, если вы используете экспресс-версию, получите копию Express Profiler для свободного доступа из CodePlex по следующей ссылке ниже

Экспресс-профайлер

Используя Sql Profiler, вы можете получить доступ ко всему, что отправляется EF в БД. В моем случае это составляло:

exec sp_executesql N'UPDATE [dbo].[Category]
SET [ParentID] = @0, [1048] = NULL, [1033] = @1, [MemberID] = @2, [AddedOn] = @3
WHERE ([CategoryID] = @4)
',N'@0 uniqueidentifier,@1 nvarchar(50),@2 uniqueidentifier,@3 datetime2(7),@4 uniqueidentifier',
@0='E060F2CA-433A-46A7-86BD-80CD165F5023',@1=N'I-Like-Noodles-Do-You',@2='EEDF2C83-2123-4B1C-BF8D-BE2D2FA26D09',
@3='2014-01-29 15:30:27.0435565',@4='3410FD1E-1C76-4D71-B08E-73849838F778'
go

Я скопировал это в окно запроса на Sql Server и выполнил его. Разумеется, хотя он и запущен, на этот запрос повлияло 0 записей, поэтому ошибка возвращается EF.

В моем случае проблема была вызвана CategoryID.

Не было идентификатора категории, идентифицированного идентификатором EF, отправленного в базу данных, поэтому пострадали 0 записей.

Это был не EF-недостаток, а скорее неправильный коллапс "??" выражение в диспетчере представлений, который посылал глупость до уровня данных.

2

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

ИЛИ

Это также может произойти, если все назначенные свойства объекта были назначены с теми же значениями, что и раньше.

        using(var db = new MyContext())
        {
            var address = db.Addresses.FirstOrDefault(x => x.Id == Id);

            address.StreetAddress = StreetAddress; // if you are assigning   
            address.City = City;                   // all of the same values
            address.State = State;                 // as they are
            address.ZipCode = ZipCode;             // in the database    

            db.SaveChanges();           // Then this will throw that exception
        }
2

Если вы пытаетесь создать сопоставление в вашем файле edmx в "функции Imports", это может привести к этой ошибке. Просто очистите поля для вставки, обновления и удаления, которые находятся в Картографических данных для данного объекта в вашем edmx, и он должен работать. Надеюсь, я дал понять.

1

Когда принятый ответ сказал ", это не приведет к перезаписыванию изменений, которые ваше приложение не знало, произошло", я был скептичен, потому что мой объект был недавно создан. Но потом оказывается, что к таблице добавлен INSTEAD OF UPDATE, INSERT- TRIGGER, который обновлял вычисленный столбец той же таблицы.

Как только я изменил это на AFTER INSERT, UPDATE, он работал нормально.

1

Ни один из вышеперечисленных ответов не полностью охватил мою ситуацию и решение проблемы.

Код, в котором ошибка была указана в контроллере MVC5:

        if (ModelState.IsValid)
        {
            db.Entry(object).State = EntityState.Modified; 
            db.SaveChanges(); // line that threw exception
            return RedirectToAction("Index");
        }

Я получил это исключение, когда я сохранял объект в режиме редактирования. Причина, по которой это бросила, состояла в том, что, когда я вернулся, чтобы сохранить его, я изменил свойства, которые сформировали первичный ключ на объекте. Таким образом, установка его состояния в Modified не имела никакого смысла для EF - это была новая запись, а не ранее сохраненная.

Вы можете решить эту проблему либо A), чтобы изменить вызов сохранения, либо добавить объект, либо B) просто не изменяйте первичный ключ при редактировании. Я сделал B).

1

У вас была такая же проблема.

Я использую EF 6, Code First + Migrations. Проблема заключалась в том, что наш администратор баз данных создал ограничение на таблицу, которая запустила ошибку.

1
    public void Save(object entity)
    {
        using (var transaction = Connection.BeginTransaction())
        {
        try
                {
                    SaveChanges();
                    transaction.Commit();
                }
                catch (OptimisticConcurrencyException)
                {
                    if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Deleted || ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Modified)
                        this.Refresh(RefreshMode.StoreWins, entity);
                    else if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Added)
                        Detach(entity);
                    AcceptAllChanges(); 
                    transaction.Commit();
                }
        }
    }
  • 0
    Не могли бы вы уточнить, на что здесь ссылается «это» и что такое ObjectStateManager? Я пытаюсь это сделать в нашем базовом классе репозитория, но получаю ошибки
1

Я столкнулся с этим с помощью Telerik RadGrid. У меня был первичный ключ как столбец с сеткой, который был установлен только для чтения. Это будет нормально работать, если столбец был отображен = "false", но readonly = "true" вызвало проблему. Я решил это, указав отображение столбца сетки = false и добавив отдельный столбец шаблона для отображения

<telerik:GridBoundColumn HeaderText="Shouldnt see" Display="false" 
     UniqueName="Id" DataField="Id">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn HeaderText="Id" UniqueName="IdDisplay">
    <ItemTemplate>
        <asp:Label ID="IDLabel" runat="server" 
            Text='<%# Eval("Id") %>'></asp:Label>                               
    </ItemTemplate>
</telerik:GridTemplateColumn> 
0

Это случилось со мной. Я запускал Aurora (AWS MySQL) и пытался добавлять записи в таблицу. Поле, отмеченное [Key] в модели, было сопоставлено с автоматически увеличивающимся полем в таблице... или так я думал. Он был установлен как первичный ключ, но он не был настроен на автоматическое увеличение. Поэтому, чтобы настроить автоматическое увеличение, я исправил свою проблему.

0

Это случилось со мной из-за несоответствия между datetime и datetime2. Как ни странно, он работал отлично до того, как тестер обнаружил проблему. Моя первая модель кода включала DateTime как часть первичного ключа:

[Key, Column(Order = 2)]  
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;

Сгенерированный столбец является столбцом datetime. При вызове SaveChanges EF генерирует следующий SQL:

-- Region Parameters
DECLARE @0 Int = 2
DECLARE @1 Int = 25
DECLARE @2 Int = 141051
DECLARE @3 DateTime2 = '2017-07-27 15:16:09.2630000' --(will not equal a datetime value)
-- EndRegion
UPDATE [dbo].[OrganizationSurvey]
SET [OrganizationSurveyStatusId] = @0
WHERE ((([SurveyID] = @1) AND ([OrganizationID] = @2)) AND ([PurchasedDate] = @3))

Поскольку он пытался сопоставить столбец datetime с значением datetime2, он не возвращал результатов. Единственное решение, о котором я подумал, это изменить столбец на datetime2:

[Key, Column(Order = 2, TypeName = "DateTime2")]  
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;
  • 1
    Странность того, что он работает против не работает, связана с базовым форматом / основанием datetime и datetime2 / datetime datetime2 . По существу, некоторые значения в миллисекундах будут соответствовать друг другу, другие - нет. То же самое случилось со мной, и я также переключился на DateTime2 .
0

У меня была проблема с идентификатором Mvc при регистрации нового пользователя, а не:

var result = await UserManager.CreateAsync(user);

Я делал:

var result = await UserManager.UpdateAsync(user);
0

мы забыли упоминать "enctype" размещение "многочастных" данных формы. Один из моих других сценариев, с которыми я сейчас сталкиваюсь...

0

Аналогичная проблема возникает при удалении элемента из таблицы (ParentTable), на который ссылались другие внешние ключи таблицы с правилом ON DELETE CASCADE (RefTable1, RefTable2). Проблема возникает из-за "ПОСЛЕ УДАЛЕНИЯ" триггера в одной из ссылочных таблиц (RefTable1). Этот триггер удалял связанную запись из ParentTable в результате, также была удалена запись RefTable2. Похоже, что Entity Framework, в то время как внутри-код был явно установлен для удаления записи ParentTable, удалял связанную запись из RefTable1, а затем записывал из RefTable2 после последней операции, это исключение было выбрано, потому что триггер уже удалил запись из ParentTable, которая в результате удалила запись RefTable2.

0

У меня есть это исключение, и я установил столбец id в качестве автоматического увеличения в моем database table, а затем он отлично работает

0

Для тех, кто использует AutoMapper Если вы обновляете сущность, которая имеет внешние ключи для другого объекта (или сущностей), убедитесь, что все внешние объекты имеют свой первичный ключ, установленный в базу данных, сгенерированную (или автоматически увеличивающуюся для MySQL).

Например:

public class BuyerEntity
{
    [Key]
    public int BuyerId{ get; set; }

    public int Cash { get; set; }

    public List<VehicleEntity> Vehicles { get; set; }

    public List<PropertyEntity> Properties { get; set; }

}

Транспортные средства и свойства хранятся в других таблицах, кроме покупателей. Когда вы добавляете нового покупателя, AutoMapper и EF автоматически обновляют таблицы "Транспортные средства" и "Свойства", поэтому, если у вас нет автоматического инкремента, установленного в любой из этих таблиц (например, я этого не сделал), тогда вы увидите ошибку вопрос ОП.

0

В последнее время я пытаюсь обновить EF5 до примера EF6. Таблица примерного проекта имеет десятичные (5,2) столбцы типа. Миграция базы данных успешно завершена. Но исходное исключение семенного семени.

Модель:

    public partial class Weather
    {
    ...
    public decimal TMax {get;set;}
    public decimal TMin {get;set;}
    ...
    }

Неверная конфигурация:

public partial class WeatherMap : EntityTypeConfiguration<Weather>
{

    public WeatherMap()
    {
        ...
        this.Property(t => t.TMax).HasColumnName("TMax");
        this.Property(t => t.TMin).HasColumnName("TMin");
        ...
    }
}

Данные:

    internal static Weather[] data = new Weather[365]
    {
      new Weather() {...,TMax = 3.30M,TMin = -12.00M,...},
      new Weather() {...,TMax = 5.20M,TMin = -10.00M,...},
      new Weather() {...,TMax = 3.20M,TMin = -8.00M,...},
      new Weather() {...,TMax = 11.00M,TMin = -7.00M,...},
      new Weather() {...,TMax = 9.00M,TMin = 0.00M,...},
    };

Я нашел проблему, данные о семени имеют значения точности, но в конфигурации нет параметров точности и масштаба. TMax и TMin, определяемые десятичной (10,0) в таблице образцов.

Правильная конфигурация:

public partial class WeatherMap : EntityTypeConfiguration<Weather>
{

    public WeatherMap()
    {
        ...
        this.Property(t => t.TMax).HasPrecision(5,2).HasColumnName("TMax");
        this.Property(t => t.TMin).HasPrecision(5,2).HasColumnName("TMin");
        ...
    }
}

Мой пример проекта выполняется с помощью: MySql 5.6.14, Devart.Data.MySql, MVC4,.Net 4.5.1, EF6.01

С уважением.

0

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

  • 0
    Это именно то, что происходит в нашем сценарии. Мой вопрос - как правильно обработать этот сценарий, чтобы избежать (или игнорировать) эту ошибку? В нашем случае один метод удаляет строку и обновляет БД, но затем пытается обновить, используя исходное состояние, и, таким образом, завершается неудачей. Мне нравится идея Avenmore, которую я собираюсь попробовать.
0

У меня возникла эта проблема, когда я случайно попытался обновить объект вместо сохранения!

У меня был

 if (IsNewSchema(model))
            unitOfWork.SchemaRepository.Update(schema);
        else
            unitOfWork.SchemaRepository.Insert(schema);

когда я должен был

 if (IsNewSchema(model))
            unitOfWork.SchemaRepository.Insert(schema);
        else
            unitOfWork.SchemaRepository.Update(schema);
  • 0
    Это то же самое, вероятно, у меня; однако, в моем случае я правильно назвал вставку, но только 3 из 4 записей вошли как добавленные. 4-й помечен как измененный. Я до сих пор не нашел решение просто ...
0

У меня также была эта ошибка. Существуют ситуации, когда объект может не знать о фактическом контексте базы данных, который вы используете, или Модель может отличаться. Для этого установите: EntityState.Modified; в EntityState.Added;

Для этого:

if (ModelState.IsValid)
{
context.Entry(yourModelReference).State = EntityState.Added;
context.SaveChanges();
}

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

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

  • 1
    ты гуру! это работает для меня!
0

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

context.Users.Attach(orderer);

с

if (orderer.Id > 0) {
    context.Users.Attach(orderer);
}
0

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

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

Проблема заключалась в том, что я использовал MVC Scaffolding для создания базовых репозиториев, и у них есть шаблон в их методе UpdateOrInsert, который в основном проверяет, установлен ли атрибут Key перед тем, как он добавит новый объект или изменит его состояние изменено.

Поскольку Guid был установлен, он пытался изменить строку, которая на самом деле не существовала в базе данных.

Я надеюсь, что это поможет кому-то еще!

0

Я выброшу это на случай, если кто-то столкнется с этой проблемой при работе в параллельном цикле:

Parallel.ForEach(query, deet =>
{
    MyContext ctx = new MyContext();
    //do some stuff with this to identify something
    if(something)
    {
         //Do stuff
         ctx.MyObjects.Add(myObject);
         ctx.SaveChanges() //this is where my error was being thrown
    }
    else
    {
        //same stuff, just an update rather than add
    }
}

Я изменил его на следующее:

Parallel.ForEach(query, deet =>
{
    MyContext ctxCheck = new MyContext();
    //do some stuff with this to identify something
    if(something)
    {
         MyContext ctxAdd = new MyContext();
         //Do stuff
         ctxAdd .MyObjects.Add(myObject);
         ctxAdd .SaveChanges() //this is where my error was being thrown
    }
    else
    {
        MyContext ctxUpdate = new MyContext();
        //same stuff, just an update rather than add
        ctxUpdate.SaveChanges();
    }
}

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

0

Получите эту ошибку при использовании SaveChanges (false), а затем позже SaveChanges() в том же контексте, в unitofwork, где несколько строк были удалены из двух таблиц (в контексте) (SaveChanges (False) был в одном из Затем в вызывающей функции вызывается SaveChanges(). Решение заключалось в том, чтобы удалить ненужные SaveChanges (false).

0

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

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

Мы решили это, проверив значение свойства и назначая только новое, если оно отличается.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню