Entity Framework Core: "Second operation started before previous completed" error
06:22 29 Dec 2025

i have problem according an api that is the supposed to get analytics of most won challenges in gamification system , it's supposed to get the top 3 won challenges data based on how many distinct users got milestone on that challenge , this is my query that cause the error

var topChallenges = await ChallengeRepository.GetAllAsQueryable()
    .Where(c =>
        c.ChallengeStatus != ChallengeStatusEnum.Draft &&
        (!request.Data.MainDate.From.HasValue || c.StartDate >= request.Data.MainDate.From) &&
        (!request.Data.MainDate.To.HasValue || c.EndDate <= request.Data.MainDate.To) &&
        (!request.Data.IsDeleted.HasValue || c.IsDeleted == request.Data.IsDeleted) &&
        (request.Data.ChallengeStatus == null || request.Data.ChallengeStatus.Contains(c.ChallengeStatus)) &&
        (request.Data.Segments == null || request.Data.Segments.Count == 0 ||
         c.ChallengeFilters.Any(s => request.Data.Segments.Select(x => x.Value).Contains(s.Value)))
    )
    .OrderByDescending(c => c.Milestones.Select(m => m.UserId).Distinct().Count())
    .Take(3)
    .Select(c => new
    {
        c,
        DistinctUserCount = c.Milestones.Select(m => m.UserId).Distinct().Count(),
        Name = c.ChallengeResources
                .Where(r => r.SupportedLanguageId == Language.Id)
                .Select(r => r.Name)
                .FirstOrDefault(),
        ImagePath = c.ChallengeImages
                     .OrderBy(ci => ci.Id)
                     .Select(ci => ci.Image)
                     .FirstOrDefault()
    })
    .AsNoTracking()
    .ToListAsync();

then i tried to enhance it by not doing the same distinct user count calculation twice at the same time

and i tried this approach

var filteredChallenges = await ChallengeRepository.GetAllAsQueryable()
    .Where(c =>
        c.ChallengeStatus != ChallengeStatusEnum.Draft &&
        (!request.Data.MainDate.From.HasValue || c.StartDate >= request.Data.MainDate.From) &&
        (!request.Data.MainDate.To.HasValue || c.EndDate <= request.Data.MainDate.To) &&
        (!request.Data.IsDeleted.HasValue || c.IsDeleted == request.Data.IsDeleted) &&
        (request.Data.ChallengeStatus == null || request.Data.ChallengeStatus.Contains(c.ChallengeStatus)) &&
        (request.Data.Segments == null || request.Data.Segments.Count == 0 ||
         c.ChallengeFilters.Any(s => request.Data.Segments.Select(x => x.Value).Contains(s.Value)))
    )
    .Select(c => new
    {
        c.Id,
        c.ChallengeStatus,
        c.StartDate,
        c.EndDate,
        DistinctUserCount = c.Milestones.Select(m => m.UserId).Distinct().Count(),
        Name = c.ChallengeResources
                .Where(r => r.SupportedLanguageId == Language.Id)
                .Select(r => r.Name)
                .FirstOrDefault(),
        ImagePath = c.ChallengeImages
                     .OrderBy(ci => ci.Id)
                     .Select(ci => ci.Image)
                     .FirstOrDefault()
    })
    .AsNoTracking()
    .ToListAsync(); 

var topChallenges = filteredChallenges
    .OrderByDescending(c => c.DistinctUserCount)
    .Take(3)
    .ToList();

then i tried another approach to remove .Include(c => c.milestones)

and to completely sperate calculations into different steps using this approach

var challengeIdsWithCounts = await ChallengeRepository.GetAllAsQueryable()
     .Where(c =>
         c.ChallengeStatus != ChallengeStatusEnum.Draft &&
         (!request.Data.MainDate.From.HasValue || c.StartDate >= request.Data.MainDate.From) &&
         (!request.Data.MainDate.To.HasValue || c.EndDate <= request.Data.MainDate.To) &&
         (!request.Data.IsDeleted.HasValue || c.IsDeleted == request.Data.IsDeleted) &&
         (request.Data.ChallengeStatus == null || request.Data.ChallengeStatus.Contains(c.ChallengeStatus)) &&
         (request.Data.Segments == null || request.Data.Segments.Count == 0 ||
          c.ChallengeFilters.Any(s => request.Data.Segments.Select(x => x.Value).Contains(s.Value)))
     )
     .Select(c => new
     {
         ChallengeId = c.Id,
         DistinctUserCount = c.Milestones.Select(m => m.UserId).Distinct().Count() // Database does the counting
     })
     .AsNoTracking()
     .ToListAsync();

var topChallengeIds = challengeIdsWithCounts
    .OrderByDescending(c => c.DistinctUserCount)
    .Take(3)
    .Select(c => c.ChallengeId)
    .ToList();

var topChallenges = await ChallengeRepository.GetAllAsQueryable()
    .Where(c => topChallengeIds.Contains(c.Id))
    .Select(c => new
    {
        c.Id,
        c.ChallengeStatus,
        c.StartDate,
        c.EndDate,
        DistinctUserCount = c.Milestones.Select(m => m.UserId).Distinct().Count(),
        Name = c.ChallengeResources
                .Where(r => r.SupportedLanguageId == Language.Id)
                .Select(r => r.Name)
                .FirstOrDefault(),
        ImagePath = c.ChallengeImages
                     .OrderBy(ci => ci.Id)
                     .Select(ci => ci.Image)
                     .FirstOrDefault()
    })
    .AsNoTracking()
    .ToListAsync();

topChallenges = topChallenges
    .OrderByDescending(c => c.DistinctUserCount)
    .ToList();

and in all 3 approaches i keep getting this error

Something went wrong 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. SourceContext: (Dsquares.Logging.Middleware.Request_Respons_Middleware)

i even checked the link on how to avoid threading issues on microsoft , but i still can't figure out what is the problem ? also my db context is registered as scoped not singleton

c# .net entity-framework linq entity-framework-core