2010-01-16 3 views
9

Pour un modèle de données propre, je vais revenir en arrière sur ce ...Meilleures pratiques d'infrastructure: quelle couche doit appeler SaveChanges()?

L'utilisation d'un flux de travail d'approbation à titre d'exemple, disons que dans mon application web, j'ai une page qui permet un drapeau utilisateur un MyEntityObject pour approbation. MyEntityObject a quelques propriétés qui contrôlent son flux de travail d'approbation, donc j'ai une méthode utilitaire commune là-bas appelée FlagForApproval(MyEntityObject eo).

Si la la page appel FlagForApproval() pour définir les propriétés nécessaires ne puis appelez SaveChanges() quand il est prêt, ou devrait FlagForApproval() enregistrer les modifications? Avoir la méthode utilitaire enregistrer les changements semble faire un peu plus que ce qu'on lui demande de faire (et si c'était juste une étape dans une série d'opérations?), Mais en même temps, faire appel à la page SaveChanges () et valider les données dans la base de données semble être trop proche des responsabilités de la couche de données.

pensées?

(Mise à jour: FWIW, jusqu'à présent, j'ai eu des méthodes utilitaires appel SaveChanges(), de cette façon la page ne dispose que d'une série d'exceptions à gérer, si la validation ou de données.)

Répondre

2

Mon opinion actuelle sur ce Le problème est de toujours avoir l'appel de la couche logique métier enregistrer les modifications après la validation des données. Lorsque l'utilisateur clique sur le bouton Enregistrer, je passe toutes les entités à valider vers la BLL, et il décide s'il faut enregistrer les modifications(). Je suis aussi curieux que vous, pour voir ce que disent les autres parce que ce problème (et beaucoup d'autres) me tourmente depuis que j'ai commencé avec EF.

+0

Je pense que vous êtes 100% à droite - il est très propre de garder SaveChanges à BLL et laisser décider d'effectuer ou non enregistrer. Mais je peux voir au moins 2 situations, où une exception peut être faite: 1) Le projet nécessite une validation du côté du modèle - ce n'est pas BLL, mais il doit décider si les changements doivent être sauvegardés ou non. 2) SaveChanges est exécuté après un code vraiment simple (ajout d'une entité, mise à jour des propriétés uniques d'une entité existante). Dans mon cas ce serait DAL. Donc je suppose que la meilleure solution est de suivre votre instinct et/ou votre expérience. –

0

Je ne suis pas sûr qu'il y ait une bonne ou une mauvaise réponse, mais il semble plus propre (de faire) que FlagForApproval gère le processus de démarrage du flux de travail. Cela implique de dire à DataLayer de conserver l'état de l'objet (c'est-à-dire SaveChanges). Toutefois, cela suppose que vous ayez des exigences métier stipulant qu'une fois qu'un flux de travail est démarré, l'état doit être conservé, de sorte que si quelque chose se produit (le serveur tombe en panne), le processus de workflow continue depuis la dernière étape.

1

La clé est de séparer la langue de base de données et de service. Si la méthode utilitaire doit enregistrer les modifications, elle le fait, si ce n'est pas le cas, indiquez clairement que ce n'est pas le cas et que des étapes supplémentaires sont nécessaires. L'utilitaire ne devrait pas avoir une méthode appelée SaveChanges, il devrait avoir des méthodes liées au processus, comme StartProcess ou LoadToBatch.

Voir l'utilitaire comme plus d'un service et ne pense pas base de données. Le "FlagForApproval" ressemble à une opération de base de données, essayez de penser à la méthode comme quelque chose comme "StartApprovalProcess" ou quelque chose d'autre lié au processus. StartApprovalProcess ferait tout le travail et commet.

S'il existe plusieurs étapes, faites en sorte que chaque étape indique indirectement qu'il peut y avoir plusieurs étapes. Seule la dernière étape s'engage. Bien que tout ce que la dernière étape peut faire est de sauvegarder les changements, make est lu comme un processus tel que move ou start.

Ex:

  1. LoadToBatchApproval (MyEntityObject eo)

  2. ValidateApprovalBatch() ...

  3. MoveBatchToProcessing() ...