1

I want to update a field by a lambda expression like this:

 packageWorkshopDtos.ForEach(p => p.WorkshopDto.ForEach(
     u => u.SubCategories = _context.School_Categories
         .Where(j => j.ParentCategoryId == u.CategoryId)
         .Select(c => c.Name)
         .ToList()));

For making this asynchronous, I did this:

  packageWorkshopDtos.ForEach(p => p.WorkshopDto.ForEach(
      async u => u.SubCategories = await _context.School_Categories
          .Where(j => j.ParentCategoryId == u.CategoryId)
          .Select(c => c.Name)
          .ToListAsync()));

But it gives me this error:

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.

How can I make it asynchronous?

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
nnmmss
  • 2,850
  • 7
  • 39
  • 67

1 Answers1

2

The way you've written it, the first ForEach starts executing all of the inner async operations simultaneously, which causes the error. My advice is: quit using the .ForEach method. It's terrible for readability, can only be used on Lists, and causes confusion like in this question. Switch to foreach instead:

foreach (var packageWorkshopDto in packageWorkshopDtos)
{
    foreach (var workshopDto in packageWorkshopDto.WorkshopDto)
    {
        workshopDto.SubCategories = await _context
            .School_Categories
            .Where(category => category.ParentCategoryId == workshopDto.CategoryId)
            .Select(category => category.Name)
            .ToListAsync();
    }
}

A side advice is to give meaningful names to your lambda parameters.

Orion
  • 566
  • 4
  • 9