Ok, it's related to the context.
I have: customer.Orders.OrderDetails, filled for the customer "CHOPS". I add customer to a context c. This means that all entities in the graph are added to the context as well. (this is important)
When I alter: customer.Orders[0].OrderDetails[0].Quantity, I get a dirty entity, namely that OrderDetails entity of which I altered the quantity. This entity is in the context customer is in too.
Doing: c.Remove(customer), will remove customer from the context, the containing collections but not the entities inside these collections. This is by design, as adding an entity to a context makes the entity be usable through uniqing so another piece of code could have obtained a reference to that entity through the context and therefore removing it from that same context again, indirectly, isn't what a developer would expect, IMHO.
So, what happens? Well, even though customer has been removed from the context, the order and orderdetail objects aren't. So when I refetch customer, using the same context, I'll get the dirty entity back, as that's in the context used and fetched data is always overruled by dirty data for an entity (to mitigate the chance of ruining edits)
This can be what you want, so if you want this, the context works for you, as it provides the same instances you had, including dirty data.
If you DON'T want this, and you made it clear this is the case for you, the context doesn't work for you, as it gives back entities you want to get rid of.
Taking a step back, what you want is actually rolling back changes to entity fields. So, you want to to go back to a previous state, not to the actual state of a context. So either do one of the following:
1) don't use a context in this situation. The context gives you unique entities, but as I explained above, the unique entities are sometimes altered in your situation and if you don't want these changes to take effect, you have to manually remove them from the context. This isn't that hard, loop through the dirty entities and remove them from the context, but a little illogical.
2) the actual right thing to do here is to use SaveFields(name) on the entities being edited. So in my case, I was going to edit orderdetail entities. Say I do this in a grid (so I bound Orders[0].OrderDetails to a grid), then I first should do:
foreach(OrderDetailsEntity orderDetails in myOrder.OrderDetails)
{
orderDetails.SaveFields("BeforeEdit");
}
then proceed and let the user edit the fields. If the user cancels, and I want to re-use the state before the edit, (and only if I want to reuse the state before the edit), I have to rollback the fields:
foreach(OrderDetailsEntity orderDetails in myOrder.OrderDetails)
{
orderDetails.RollbackFields("BeforeEdit");
}
and I'm back to the previous state. I don't have to re-fetch data (saves you roundtrips to the DB), and I also don't have dirty entities anymore as the data has been rolled back.