Почему Entity Framework пытается обновить более одной строки, когда я сохраняю свои изменения? - PullRequest
0 голосов
/ 04 мая 2019

У меня есть метод ниже, и когда запускается сохранение изменений, Entity Framework пытается обновить более одной строки? Даже если я изменяю дату только для одной записи и выбираю одну запись для изменения.

Error

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: ожидается, что операция с базой данных повлияет на 1 строку (и), но фактически повлияет на 2 строку (и). Данные могут быть изменены или удалены с момента загрузки объектов.

Метод

    public static async Task<HttpResult> PostRecordCoworkerStartDateAsync(MpidDbContext context, int id, RecordCoworker recordCoworker)
    {
        // just testing to see how many are returned
        int testCount = context.RecordsCoworkers.Where(m => m.Id == id && m.IsActive == true).ToList().Count();

        RecordCoworker recordCoworkerToUpdate = context.RecordsCoworkers.SingleOrDefault(m => m.Id == id && m.IsActive == true);

        recordCoworkerToUpdate.StartDate = recordCoworker.StartDate;

        try
        {
            await context.SaveChangesAsync();
        } catch(Exception ex)
        {
            var i = ex;
        }

        return HttpResult.NoContent;
    }

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

SET NOCOUNT ON;
UPDATE [Records_Coworkers] SET [StartDate] = @p0
WHERE [RecordID] = @p1 AND [CoworkerID] = @p2;
SELECT @@ROWCOUNT;

По сути, я просто хочу обновить одну запись, в которой «IsActive» имеет значение true. Но запрос, поскольку он удаляет свойство IsActive, попытается обновить две или более строки.

Ответы [ 2 ]

1 голос
/ 04 мая 2019

Просто чтобы объяснить, почему:

  1. Вы запрашиваете в базе данных всех активных пользователей с определенным идентификатором и берете первый результат.
  2. Entity Framework отправляет запрос и материализует результат в объект.
  3. Вы меняете собственность.
  4. Entity Framework будет устанавливать состояние объекта для изменения.
  5. Вы вызываете SaveChanges, чтобы сообщить EF, что он отправляет изменения обратно в базу данных.
  6. Как известно, какой идентификатор у объекта, он напрямую рассматривается в операторе обновления.

Это две операции: SELECT и UPDATE. Они выполняются отдельно, так как Entity Framework не знает: что вы делаете тем временем (до тех пор, пока не позвоните SaveChanges) сущности?

Присвоение [ConcurrencyCheck] свойству сообщает Entity Framework, что оно должно обеспечить, чтобы во время UPDATE значение свойства IsActive было таким же, как и во время SELECT. Когда в эту базу данных записываются разные приложения, это гарантирует, что ни одно из других приложений не изменило сущность в течение времени между SELECT и UPDATE.

Вы должны удалить строку int testCount. Или запросить их как неотслеживаемые.

0 голосов
/ 04 мая 2019

Я выяснил почему.

В моей сущности мне нужно было добавить атрибут данных в свойство IsActive

    [Required]
    [ConcurrencyCheck]
    public bool IsActive { get; set; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...