abp icon indicating copy to clipboard operation
abp copied to clipboard

I have a bug deleting an entity and soft delete does not seem to be applied. instead of marking the deleted field, it does hard delete

Open ktngoykalolo opened this issue 1 year ago • 9 comments

  • ABP version 8.
  • MVC single-Layer template
  • EfCore
  • when deleting an entity, I have the below exception being thrown by the Repository. It seems that the DBContext is being called twice.
  • it also seems that the soft delete does not work at all
  • System.InvalidOperationException HResult=0x80131509 Message=A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913. Source=Microsoft.EntityFrameworkCore StackTrace: at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection() at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.Enumerator.MoveNext() at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable1 source, Boolean& found) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression) at Microsoft.EntityFrameworkCore.Internal.EntityFinder1.GetDatabaseValues(InternalEntityEntry entry) at Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry.GetDatabaseValues() at Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry.Reload() at Volo.Abp.EntityFrameworkCore.AbpDbContext1.ApplyAbpConceptsForDeletedEntity(EntityEntry entry) at Volo.Abp.EntityFrameworkCore.AbpDbContext1.PublishEventsForTrackedEntity(EntityEntry entry) at Volo.Abp.EntityFrameworkCore.AbpDbContext1.ChangeTracker_StateChanged(Object sender, EntityStateChangedEventArgs e) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.OnStateChanged(InternalEntityEntry internalEntityEntry, EntityState oldState) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.FireStateChanged(EntityState oldState) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable1 forceStateWhenUnknownKey, Nullable1 fallbackState) at Microsoft.EntityFrameworkCore.DbContext.RemoveRange(IEnumerable1 entities) at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository2.<DeleteManyAsync>d__27.MoveNext() at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository2.<DeleteAsync>d__36.MoveNext() at Castle.DynamicProxy.AsyncInterceptorBase.<ProceedAsynchronous>d__13.MoveNext() at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapter.<ProceedAsync>d__7.MoveNext() at Volo.Abp.Uow.UnitOfWorkInterceptor.<InterceptAsync>d__2.MoveNext() at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.<InterceptAsync>d__2.MoveNext() at Komatel.Perenco.TrackingApp.Services.CostCenterAppService.<DeleteCostCenter>d__9.MoveNext() in C:\Users\ktngo\OneDrive\Documents\Visual Studio 2022\Komatel.Perenco.TrackingApp\Komatel.Perenco.TrackingApp\Komatel.Perenco.TrackingApp\Services\CostCenterAppService.cs:line 127 at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_1(Object state) at System.Threading.QueueUserWorkItemCallback.Execute() at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()

ktngoykalolo avatar May 06 '24 19:05 ktngoykalolo

using Komatel.Perenco.TrackingApp.Entities;
using Komatel.Perenco.TrackingApp.Services.Dtos;
using Komatel.Perenco.TrackingApp.Services.Interfaces;
using Volo.Abp.Domain.Repositories;
using Komatel.Perenco.TrackingApp.ObjectMapping;
using Volo.Abp.Application.Dtos;
using Komatel.Perenco.TrackingApp.Data;
using Komatel.Perenco.TrackingApp.Entities.Interfaces;



namespace Komatel.Perenco.TrackingApp.Services
{
    public class CostCenterAppService : TrackingAppAppService, ICostCenterAppService
    {

        private readonly ICostCenterRepository _costCenterRepository;
        private readonly IRepository<ServiceCostCenter> _serviceCostCenterRepository;




        public CostCenterAppService()
        { }
        public CostCenterAppService(ICostCenterRepository CostCenterRepo, IRepository<ServiceCostCenter> serviceCostCenterRepo)
        {
            _costCenterRepository = CostCenterRepo;
            _serviceCostCenterRepository = serviceCostCenterRepo;
        }



        //public async Task<List<CostCenterDto>> GetCostCentersAsync()
        //{
        //    var costCenters = await _costCenterRepository.GetListAsync();

        //    var dtos = new List<CostCenterDto>();

        //    dtos = ObjectMapper.Map<List<CostCenter>, List<CostCenterDto>>(costCenters, dtos);

        //    return dtos;
        //}

        public async Task<PagedResultDto<CostCenterDto>> GetCostCentersAsync(GetCostCenterListDto input)
        {
            var costCenters = await _costCenterRepository.GetListAsync();

            var dtos = new List<CostCenterDto>();

            dtos = ObjectMapper.Map<List<CostCenter>, List<CostCenterDto>>(costCenters, dtos);


            if (input.Sorting.IsNullOrWhiteSpace())
            {
                input.Sorting = nameof(CostCenter.Name);
            }

            var costs = await _costCenterRepository.GetListAsync(
                input.SkipCount,
                input.MaxResultCount,
                input.Sorting,
                input.Filter
            );

            var totalCount = input.Filter == null
                ? await _costCenterRepository.CountAsync()
                : await _costCenterRepository.CountAsync(
                    cost => cost.Name.Contains(input.Filter));

            return new PagedResultDto<CostCenterDto>(
                totalCount,
                ObjectMapper.Map<List<CostCenter>, List<CostCenterDto>>(costs)
            );
        }



        public async Task<CostCenterDto> GetCostCenter(Guid Id)
        {
            var costCenters = await _costCenterRepository.GetAsync(Id);


           
           var dto = ObjectMapper.Map<CostCenter, CostCenterDto>(costCenters);

            return dto;

        }

        public async Task<List<ServiceCostCenterDto>> GetCostCentersAndServices(Guid costcenterid)
        {
            var serviceCostCenters = await _serviceCostCenterRepository.GetListAsync(c => c.CostCenterId == costcenterid);

            var dtos = new List<ServiceCostCenterDto>();

            dtos = ObjectMapper.Map<List<ServiceCostCenter>, List<ServiceCostCenterDto>>(serviceCostCenters, dtos);

            return dtos;
        }

        public async void CreateCostCenterAsync(CostCenterDto dto)
        {

            var costcenter = ObjectMapper.Map<CostCenterDto, CostCenter>(dto);

           await _costCenterRepository.InsertAsync(costcenter);

           

        }


        public async void UpdateCostCenter(CostCenterDto dto)
        {

            var costcenter = ObjectMapper.Map<CostCenterDto, CostCenter>(dto);

            await _costCenterRepository.UpdateAsync(costcenter);


        }

        public async void DeleteCostCenter(Guid id)
        {

          
            await _costCenterRepository.DeleteAsync(x => x.Id == id);


        }

     

        Task<List<CostCenterDto>> ICostCenterAppService.GetCostCentersAsync()
        {
            throw new NotImplementedException();
        }
    }
}

ktngoykalolo avatar May 06 '24 19:05 ktngoykalolo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Komatel.Perenco.TrackingApp.Entities;
using Komatel.Perenco.TrackingApp.Entities.Interfaces;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;


namespace Komatel.Perenco.TrackingApp.Data
{
    public class EfCoreCostCenterRepository : EfCoreRepository<TrackingAppDbContext, CostCenter, Guid>, ICostCenterRepository
    {
        public EfCoreCostCenterRepository(IDbContextProvider<TrackingAppDbContext> dbContextProvider) : base(dbContextProvider)
        {
        }

        public async Task<List<CostCenter>> GetListAsync(int skipCount, int maxResultCount, string sorting, string filter)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    cost => cost.Name.Contains(filter)
                 )
                .OrderBy(sorting)
                .Skip(skipCount)
                .Take(maxResultCount)
                .ToListAsync();
        }
    }
}

ktngoykalolo avatar May 06 '24 19:05 ktngoykalolo

hi

Please change all return type from async void to async Task .

maliming avatar May 07 '24 01:05 maliming

hi @maliming , I need to change on the repositories and the Appservice ?

ktngoykalolo avatar May 08 '24 10:05 ktngoykalolo

hi

You have to change all the code like this. Never use async void as the return type for async methods.

maliming avatar May 08 '24 11:05 maliming

noted but now I am getting the following error with update method. "The data you have submitted has already changed by another user/client. Please discard the changes you've done and try from the beginning."

ktngoykalolo avatar May 08 '24 14:05 ktngoykalolo

public async Task UpdateCostCenter(CostCenterDto dto)
{
    var costcenter = _costCenterRepository.GetAsync(dto.Id);
    ObjectMapper.Map<CostCenterDto, CostCenter>(dto, costcenter);
    await _costCenterRepository.UpdateAsync(costcenter);
}

maliming avatar May 09 '24 01:05 maliming

hello, will try the changes and advise. I suspect I was not properly mapping the objects with automapper.

ktngoykalolo avatar May 09 '24 15:05 ktngoykalolo

https://docs.abp.io/en/abp/latest/Object-To-Object-Mapping

maliming avatar May 10 '24 00:05 maliming