问题
not sure if this is a breeze question or an EF question. I have a SaveChanges map that contains inserts/deletes/updates. I have business rule validations that involve multiple entities and relationships between them, so I can't do the complete validation until I know all the changes. The same validation logic is performed on the client, but I am re-validating on the server.
What I am looking for is some way to apply the complete sql batch of updates, but before the transaction is committed I would like to do the validations to see if the change set as a whole is valid. If not, then I roll back. of course the validations would have to be done within the same context/transaction as the updates so I have access to the changes.
I'm already doing validation in BeforeSaveEntities but thats more of a security check, (can this user update this record). Thats simple and straightforward.
An example business rule for a change set that contains a customer record and 1 or more address records, and/or 1 or more contact records: If the customer is assigned to Industry A then it must have exactly 1 address coded as "Primary" and that address must have at least 1 contact associated with it.
Trying to do that validation by evaluating the existing state and the complete set of changes seems like a lot of work and error prone. There could be multiple addresses/contacts being added, deleted, or updated. It could very easily be done by a simple SQL select after all the updates have been applied, prior to commit.
Is this even possible? What are my options? thanks
回答1:
Ok, this does need to be documented better but this should provide a start:
http://www.breezejs.com/documentation/efcontextprovider-methods
You can use the Breeze.AfterSaveEntities method in conjunction with a TransactionSettings instance that uses a TransactionType of TransactionScope.
This insures that the entire save occurs within a TransactionScope (including the BeforeSaveEntities and the AfterSaveEntities). this means that if you throw an Exception inside of your AfterSaveEntities method, it will abort the transaction, and rollback any previous inserts, updates or deletes that were part of the transaction.
[HttpPost]
public SaveResult SaveWithTransactionScope(JObject saveBundle) {
var txSettings = new TransactionSettings() { TransactionType = TransactionType.TransactionScope };
ContextProvider.AfterSaveEntitiesDelegate = PerformPostSaveValidation;
return ContextProvider.SaveChanges(saveBundle, txSettings);
}
private void PerformPostSaveValidation(Dictionary<Type, List<EntityInfo>> saveMap, List<KeyMapping> keyMappings ) {
// do your validation stuff here
// and throw an exception if something doesn't validate.
}
I hope this makes sense :)
来源:https://stackoverflow.com/questions/20416587/breezejs-and-entity-framework-validation-after-updates-but-before-commit