For a clean data model, I'm going back and forth on this...
Using an approval workflow as an example, let's say in my web application I have a page that lets a user flag a MyEntityObject
for approval. MyEntityObject
has a few properties that control its approval workflow, so I have a common utility method out there called FlagForApproval(MyEntityObject eo)
.
Should the page call FlagForApproval() to set necessary properties only and then call SaveChanges() when it's ready, or should FlagForApproval() save the changes?
Having the utility method save changes seems like it's doing a little more than it's asked to do (what if it was just one step in a series of operations?), but at the same time开发者_如何学C, making the page call SaveChanges() and commit the data to the DB seems like it could be considered too close to data layer responsibilities.
Thoughts?
(Update: FWIW, so far I have been having utility methods call SaveChanges(), that way the page only has one set of exceptions to handle, whether validation or data.)
My current opinion on this issue is to always have the business logic layer call save changes after validating data. When the user clicks Save button, i pass whatever entities need to be validated down to the BLL, and it decides whether to SaveChanges().
I'm as curious as you though, to see what others say because this issue (and many other) has been plaguing me since i started with EF.
The key is to separate Database and Service language. If the utility method needs to save changes then it does, if not make it clear that it does not and additional steps are needed. The utility should not have a method called SaveChanges, it should have process related methods, like StartProcess or LoadToBatch.
View the utility as more of a service and do not think database. The "FlagForApproval" sounds like a database operation, try thinking of the method as something like "StartApprovalProcess" or something else process related. StartApprovalProcess would do all work and commits.
If there are multiple steps, make each step indicate indirectly that there may be more steps. Only the last step commits. Allthough all the last step may do is save changes, make is read like a process such as move or start.
Ex:
LoadToBatchApproval(MyEntityObject eo)
ValidateApprovalBatch()...
MoveBatchToProcessing()...
I'm not sure there is a right or wrong answer, but it feels cleaner (imo) to have FlagForApproval handle the process for starting the workflow. That includes telling the DataLayer to persist the state of the object (i.e. SaveChanges). However this assumes that you have business requirements stating that once a workflow is started the state should be persisted so if something happens (i.e. server crashes) the workflow process continues from last step.
精彩评论