Foreach to linq with async calls

Newbie Dev 156 Reputation points
2023-10-01T19:36:40.0666667+00:00

I have a nested for loop with async calls in it. How would I go about converting it to Linq?

foreach (var fruit in Fruits) 
{     
	var fruit = await _fruitRepository.GetFruitAsync(fruit.fruitId);     
	if(fruit != null)     
	{      
		foreach (var color in fruit.colors)     
		{        
 		var fruitColor = await _colorRepository.GetColorAsync(color.colorId);  

	    if(fruitColor != null)        
		{         
			await _FruitColorRepository.SaveFruitColorAsync(fruit.fruitId, fruitColor);        
		}     
		}    
	} 
}
Developer technologies C#
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2023-10-01T21:02:16.6266667+00:00

    your goal is unclear. you goal unclear, linq is for returning an mapping of an object, but you code just does an update. as linq does not have a ForEach() as it does not designed for void results, what did you want the result to be?

    assuming you don't care what's returned (this sample is a collection of collection of ints):

    Fruits.Select(async fruit => (await _fruitRepository.GetFruitAsync(fruit.fruitId))
        .colors
        .Select(async color => 
        { 
            var fruitColor = await _colorRepository.GetColorAsync(color.colorId);  
    		await _FruitColorRepository.SaveFruitColorAsync(fruit.fruitId, fruitColor);  
            return 0; // don't keep allocations
        })
    );  
    

  2. Anonymous
    2023-10-02T02:37:50.1966667+00:00

    Hi @Newbie Dev , Welcome to Microsoft Q&A,

    If you think about using parallelism and efficiency. You can use Task.WhenAll to perform asynchronous operations in parallel. Then use anonymous objects to store fruit and color, which are only used once in Where and Select internally, which can avoid unnecessary memory allocation.

    await Task.WhenAll(Fruits
        .SelectMany(fruit => fruit.colors, (fruit, color) => new { fruit, color })
        .Where(async fc =>
        {
            var fruit = await _fruitRepository.GetFruitAsync(fc.fruit.fruitId);
            var fruitColor = await _colorRepository.GetColorAsync(fc.color.colorId);
            return fruit != null && fruitColor != null;
        })
        .Select(async fc =>
        {
            await _FruitColorRepository.SaveFruitColorAsync(fc.fruit.fruitId, fc.color.colorId);
        }));
    
    

    Best Regards,

    Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.