My object hierarchy is like this:
class Detail
{
public List<Row> Rows { get; set; }
}
class Row
{
public List<Column> Columns { get; set; }
}
class Column
{
public string Name { get; set; }
public bool IsUpdated { get; set; }
}
I want to set column.IsUpdated = true where column.Name = "id". I am trying this, it doesn't work.
detail.Rows.ForEach(r => r.Columns.Where(c => c.Name.ToLower().Equals("id")).ToList<Column>().Select(c => c.IsUpdated = true));
The philosophy of LINQ is to not have side effects. That's why on purpose it does not make it easy for you to do this. You could do it either with a classic
var cols = details.Rows.SelectMany(r => r.Columns)
.Where(c => c.Name.ToLower().Equals("id"));
foreach(var col in cols) {
col.IsUpdated = true;
}
or by using List.ForEach
, but in a different manner:
details.Rows.SelectMany(r => r.Columns)
.Where(c => c.Name.ToLower().Equals("id")).ToList()
.ForEach(c => { c.IsUpdated = true });
LINQ is really intended for querying data, not changing values within the data. If you want to make an entire new detail item, you could do that:
var newDetail = new Detail
{
Rows = detail.Rows.Select(r => new Row
{
Columns = r.Columns.Select(c => new Column { Name = c.Name, IsUpdated = c.Name.ToLower() == "id" ? true : c.IsUpdated }).ToList()
})
.ToList()
};
Note that the above would be cleaner, most likely, if you added constructors for your types, as well.
That being said, if you want to update it in place, like you were showing, I would just use loops:
foreach(var row in detail.Rows)
foreach(var col in row.Columns)
if (col.Name.ToLower() == "id")
col.IsUpdated = true;
I find that far easier to follow, especially in this case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With