django
django

Reputation: 210

IRepositoy.InsertOrUpdateAsync throwing concurrency exception

I was creating a content managment system on ABP using entityframework and .net core. I am getting concurrency exccetion when using InsertOrUpdateAsync. I do not have any data in my table.

Please find the Model used to create table.

   [Table("CMSContents")]
   public class CMSContent:Entity<int>
   {
       public const int MAXTITLELENGHT = 128;

       public const int MAXCONTENTLENGTH = 10000;

       [Key]
       [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
       public override int Id { get; set; }
       /// <summary>
       /// The title of the content.
       /// </summary>
       [Required]
       [StringLength(MAXTITLELENGHT)]
       public virtual string PageName { get;  set; }

       /// <summary>
       /// The Cms Content
       /// </summary>
       public virtual  string PageContent { get; set; }

       protected CMSContent()
       {

       }

       public static CMSContent CreateContent(int id,string title ,string contents)
       {
           var @content = new CMSContent
           {
               Id =  id, 
               PageName = title,
               PageContent = contents
           };

           return @content;
       }
   }
}

Below is the Application service used to call the repository.

public async Task<CMSContent> InsertOrUpdateCMSContent(CreateContentInput input)
        {
            var @content = CMSContent.CreateContent(input.Id,input.PageName, input.PageContent);
            return await _contentManager.InsertOrUpdateAsync(@content);
        }

Exception while calling this API from Swagger,

Mvc.ExceptionHandling.AbpExceptionFilter - 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. Abp.Domain.Uow.AbpDbConcurrencyException: 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. ---> 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 Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyException(Int32 commandIndex, Int32 expectedRowsAffected, Int32 rowsAffected) at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithoutPropagationAsync(Int32 commandIndex, RelationalDataReader reader, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeAsync(RelationalDataReader reader, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple2 parameters, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IReadOnlyList1 entriesToSave, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Abp.EntityFrameworkCore.AbpDbContext.SaveChangesAsync(CancellationToken cancellationToken) in D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\AbpDbContext.cs:line 224 --- End of inner exception stack trace --- at Abp.EntityFrameworkCore.AbpDbContext.SaveChangesAsync(CancellationToken cancellationToken) in D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\AbpDbContext.cs:line 230 at Abp.Zero.EntityFrameworkCore.AbpZeroCommonDbContext`3.SaveChangesAsync(CancellationToken cancellationToken) in D:\Github\aspnetboilerplate\src\Abp.ZeroCore.EntityFrameworkCore\Zero\EntityFrameworkCore\AbpZeroCommonDbContext.cs:line 170 at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.SaveChangesInDbContextAsync(DbContext dbContext) in D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\Uow\EfCoreUnitOfWork.cs:line 167 at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.SaveChangesAsync() in D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\Uow\EfCoreUnitOfWork.cs:line 68 at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.CompleteUowAsync() in D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\Uow\EfCoreUnitOfWork.cs:line 83 at Abp.Domain.Uow.UnitOfWorkBase.CompleteAsync() in D:\Github\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkBase.cs:line 273 at Abp.AspNetCore.Mvc.Uow.AbpUowActionFilter.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) in D:\Github\aspnetboilerplate\src\Abp.AspNetCore\AspNetCore\Mvc\Uow\AbpUowActionFilter.cs:line 51 at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)

Upvotes: 0

Views: 1426

Answers (1)

django
django

Reputation: 210

I have tried the following approach to make it work, posting as an answer since comment wont allow this many characters.

      public async Task<CMSContent> InsertOrUpdateCMSContent(CreateContentInput input)
    {
        var exists = await _contentRepository
            .GetAll()
            .AnyAsync(e => e.Id == input.Id);
        if (!exists)
        {
           var @content = CMSContent.CreateContent(input.PageName, input.PageContent);
            return await _contentRepository.InsertAsync(@content);
        }
        else
        {
            var @content = CMSContent.CreateContent(input.Id, input.PageName, input.PageContent);
            return await _contentRepository.UpdateAsync(@content);
        }            
    }

Upvotes: 1

Related Questions