I have the following Linq query. transactionData is an IEnumerable.
var totalTransactions = 0;
viewModel.GroupedTransactions = transactionData
.GroupBy(x => new { DocumentId = x.DocumentId ?? "Un Documented" })
.Select(x => new GroupedTransaction
{
DocumentId = x.Key.DocumentId,
Transactions = x.Select(y => new Transaction
{
Amount = y.CommitAmount,
ActivityType = y.ActivityType,
Number = totalTransactions++
})
})
.OrderBy(x => x.DocumentId);
where I’m trying to set the Number on the Transaction record to be an incremented number.
This doesn’t work, leaving gaps in the numbers.
I also tried the following after the query.
foreach (var item in viewModel.GroupedTransactions.SelectMany(x => x.Transactions))
{
item.Number = totalTransactions;
totalTransactions++;
}
This didn’t even update the Number value.
What am I doing wrong, or is there a simpler way, with a neat linq extension method?
The problem is that you are closing over the variable
totalTransactions, you have to create a local copy to use. Check Closing over the loop variable considered harmful for a more detailed explanation.Something like this should work:
For your second approach with the foreach loop – you are actually creating a new enumeration with
SelectMany()that you subsequently just throw away:Instead you have to force eager evaluation of your collection by using
ToList()to create a collection you can safely modify.