Save One, Save All in Entity Framework
I'm still learning about Unit of Work patterns, repository patterns, etc.
My app:
- I have a list of entities, say customers in a listview
- When I select a customer a detail form shows, where 开发者_运维百科their details can be edited
I'm trying to understand the standard MVVM/Entity Framework way of accomplishing the following:
- When the user edits a customer it shows as "changed" (but not saved)
- The user can chose to either save the current customer, or save all the changed customers
- The Save or Save All commands/buttons are disabled if that option is not available (the current customer is unchanged, or all customers are unchanged)
Seems simple enough? But I have no idea how to approach this using MVVM/EF. Do I use UoW, do I detach objects and re-attach to the context so I can save them one at a time? How do I detect if an object is changed or unchanged?
Help! Thanks!
I throw in a few remarks:
The critical point in your requirements is in my opinion the option to save either one single customer or all changed customers. You need to take into account that Entity Framework doesn't have a method to save changes of a single or a few selected objects in the context. You can only save the changes of the whole Unit of Work (which is the ObjectContext
or DbContext
in EF) by calling myContext.SaveChanges()
.
This leads to the conclusion that you cannot use the list of all customers and the customer detail form in one single Unit of Work (= EF context) which holds all customers as attached entities. If you would do this you could provide a function/button to save all changes but not an option to save only the current customer in the form.
So, I would either think about if you really need those functions or I would work with the entities in a detached state. This would mean that you have to load the customer list from the database and dispose the context after that. When you save the changes - and now it doesn't matter if all changes or only changes of a single customer - you can create a new context, pull the original entity/entities from the database and update with the changed properties.
But working with either attached or detached entities - or either having one living EF context per view/form or creating only one short-living context per CRUD operation - is an important design decision in my opinion. Generally the possibility to have your entities attached to a context during the lifetime of a view/form exists to make your life as programmer easier because it offers you features like lazy loading and change tracking out of the box. So you might think twice if you want to give this up.
To recognize if a customer object has been changed or not the EF context could be helpful because it tracks the state of an object. You could for instance query the ObjectStateManager for a customer and check if it is in a "Changed" state. But to have this option you would need to work with attached entities as explained above. Since you cannot save (or also cancel) single object changes it is questionable if it would make sense at all to show the user that customer 1 and customer 3 has changed. (I would probably only show "some customers have changed".)
If you are working with detached entities you have to manage by hand which customers have changed or not by implementing some kind of "dirty flag" logic. Here is a thread about this:
Different ways to implement 'dirty'-flag functionality
精彩评论