Я столкнулся с этой ошибкой в одноэлементной службе, когда два экземпляра одного и того же класса пытались использовать один и тот же метод, который использует репозиторий.
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.
at Npgsql.EntityFrameworkCore.PostgreSQL.Update.Internal.NpgsqlModificationCommandBatch.ConsumeAsync(RelationalDataReader reader, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple`2 parameters, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IReadOnlyList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
Чтобы решить эту проблему, я нашел решение, используя собственную область видимости в Autofac.
private readonly Func<Owned<IProductRepository>> productRepositoryFactory;
...
using (var repositoryOwned = productRepositoryFactory())
{
await repositoryOwned.Value.DeleteRangeAsync(idsToRemove);
}
Это решило проблему, но я боюсь, что производительность будет снижена из-за спама при создании и удалении DbContext (используемый DbContext регистрируется в зависимости от зависимости). Есть ли лучшее решение этой проблемы, которое не повлияет на производительность таким образом?
DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s).
. Это совсем не касается многопоточности или одновременного доступа к DbContext. Речь идет об оптимистичном параллелизме. Это означает, что строка, которую DbContext пытался сохранить, тем временем была изменена. Это бизнес проблема, ее нельзя исправить с помощью AutoFac или какого-либо решения по умолчанию. - person Panagiotis Kanavos   schedule 05.02.2020git
конфликты. Вы должны решить, что вы хотите сделать в этом случае - перезаписать изменения? В некоторых случаях это нормально. Отменить собственные изменения? Загрузить измененные данные и проверить, какие строки были изменены? Изменения в столбцах аудита, напримерModifiedBy
, можно безопасно игнорировать. Или вам следует спросить конечного пользователя, что ему делать? - person Panagiotis Kanavos   schedule 05.02.2020Product
, как он настроен? Каким образом два разных соединения привели к изменению одного продукта? Это действующий бизнес-сценарий? Могут ли два пользователя открыть одну и ту же страницу продукта и изменить описание или название? - person Panagiotis Kanavos   schedule 05.02.2020the change has priority over the removal
означает ли это, что вы хотите воссоздать удаленный объект? Это .... странно, если не сказать больше. Этот DELETE, вероятно, также удалил записи связующего. В любом случае исправление в этом случае состоит в том, чтобы вставить удаленные записи снова, если это возможно. - person Panagiotis Kanavos   schedule 06.02.2020Completed
,inactive
,cancelled
или что-то другое, имеющее бизнес-смысл. Когда что-то удаляется из базы данных, это значит, что оно исчезнет без следа. Если вы попали в ситуацию, когда вам нужно воскресить удаленную запись, что-то точно не так - person Panagiotis Kanavos   schedule 06.02.2020actually affected 0 row(s)
и повторить транзакцию без нее, потому что мне все равно, что запись, которую я хотел удалить, уже удалена. - person pope_yol   schedule 06.02.2020