So the scenario in a nutshell: I have an entity (EF4) that has a foreign key to the primary key in the same entity (hierarchical structure) e.g.
MyEntityId (Primary Key)
ParentMyEntityId (Foreign key to Primary Key)
If I have a MyEntityList List<MyEntity> where the EntityState for both is Unchanged:
entity 1 - {MyEntityId = 10, ParentMyEntityId = null}
entity 2 - {MyEntityId = 11, ParentMyEntityId = 10}
and then I do this:
//Initially has 2 items in 'in' clause - iterates once and then exits because the EntityState of the second item has changed to Modified
foreach(MyEntity m in MyEntityList.Where(e => e.EntityState == System.Data.EntityState.Unchanged))
{
db.DeleteObject(m);
}
The first MyEntity is deleted, but the second changes to “Modified” and the foreach doesn’t run a second time – I’m guessing due to the foreign key constraint.
However if I do:
//Iterates twice, even though the EntityState of the second item has changed to Modified
foreach(MyEntity m in MyEntityList.Where(e => e.EntityState == System.Data.EntityState.Unchanged).ToList())
{
db.DeleteObject(m);
}
Both entities are deleted (which is the desired effect).
Whilst I have a solution, I’m interested in why this happens, I was always under the impression that the iterator “set” that was defined at the start of the foreach loop remained the same, or threw a runtime error if you tried to modify it.
Should I not be using Where? Is there a better way to do this?
The iterator set is defined before the loop runs because you execute
ToList(if you didn’t do this it wouldn’t be well defined).So the iteration source is constant. But not the object you iterate over. The object references you get are constant but not the objects pointed to by them.
The version without ToList is equivalent to:
The ToList-version is equivalent to: