I'm after some advice as to whether I'm on the right track with what I'm doing. I'm developing a WPF app where I need to retrieve a large graph of entities, work on that graph in the UI (display, CRUD), then persist it all back to the database when the user eventually clicks Save. I've used the DbContext POCO code template for my entities. An added complication is that the UI needs to provide undo/redo functionality, and this is where I started to come a bit unstuck.
One of the problems with POCO is that you don't get "association fix-up", so when you add a new entity you must remember to set up the relationship on both sides (i.e.
myOrder.Customer = customer;). Alternatively I could just add the new entity to its parent collection then call DetectChanges(), which has the effect of fixing-up the other side. Either way, there are a couple of things to do when creating a new entity.
Deletions are also tricky to handle, not just in POCO but EF in general. To delete an entity I have to call DbContext.Set<>.Remove(entity), but it doesn't feel right having the UI calling into the BLL (my UI view model holds a reference to a BLL class, which in turn holds an instance of the DbContext, ensuring the context is alive from initial retrieval to subsequent saving, giving me change-tracking). Alternatively I could implement an "IsDeleted" flag on my entities, but this will complicate many areas of my application - I would have to remember to filter out entities that are pending deletion, and handle deletions manually in my business tier.
Back to the undo/redo - if I need to undo a creation, I guess I just need to remove the entity from its parent and set the parent property to null. As for undoing a deletion, I'm not sure what I need to do here. I'm guessing I have to restore the entity's state to what it was before the deletion, and fix-up both sides of the relationship again?
Edit - I've since found that undoing a creation is not straightforward. Although I've removed both sides of the relationship, the context still "knows" about the new entity. I guess I would have to detach it, but again it doesn't feel right having to call through to the BLL to perform such operations. The only other solution I can think of to all this is to manage the graph in a "detached" state, and implement a flag on my entities to track its state (new/updated/deleted). I would then have to manually manage adding/attaching everything to the context when the graph is passed back to the BLL during saving.