The code in the post demonstrates why doing updates of objects in .Select
(or other LINQ methods) is bad idea:
- no one ever expect modification to happen, do not expect result to persist or variations of those two
- delayed/lazy execution of LINQ queries makes it very hard to see what is happening. Code will work fine while debugging and looking at results then fail while running on its own.
Problem with original code - Where
and Select
are lazily evaluated and hence nothing requests enumeration of the result no evaluation actually happens. To fix - forcing iteration would work. Use .ToList()
or .All(...)
as shown in Query and updating a property in a collection using LINQ.
foreach (var store in stores)
{
store.SelectedBooks
.Where(d => d.BookID == priceBookId )
.Select(x => {x.IsPriceBook = true; return 42; }) // return anything
.ToList(); // force iteration with `ToList`
}
You can even remove outer foreach
stores.SelectMany(r =>r.SelectedBooks)
.Where(d => d.BookID == priceBookId )
.All(x => {x.IsPriceBook = true; return true; }); // force iteration with All
Indeed fixing code that way will be consider as "hack" and really you should first select item and that act on them:
foreach (var book in
stores.SelectMany(store => store.SelectedBooks)
.Where(d => d.BookID == priceBookId ))
{
book.IsPriceBook = true;
}