Actuellement, nous utilisons NHibernate pour mapper des objets métier aux tables de base de données. Ces objets métier appliquent les règles métier: Les accesseurs set jetteront une exception sur place si le contrat pour cette propriété est violé. De plus, les propriétés imposent des relations avec d'autres objets (parfois bidirectionnels!). Eh bien, chaque fois que NHibernate charge un objet de la base de données (par exemple lorsque ISession.Get (id) est appelée), les accesseurs définis des propriétés mappées sont utilisés pour placer les données dans l'objet.Avec quelles classes dois-je mapper avec NHibernate?
Ce qui est bien, c'est que le niveau intermédiaire de l'application applique la logique métier. Ce qui est mauvais c'est que la base de données ne le fait pas. Parfois, la merde trouve son chemin dans la base de données. Si la merde est chargée dans l'application, elle est bloquée (lève une exception). Parfois, il devrait clairement être libéré sous caution parce qu'il ne peut rien faire, mais que faire s'il peut continuer à fonctionner? Par exemple, un outil d'administration qui rassemble des rapports en temps réel risque fortement d'échouer inutilement au lieu de permettre à un administrateur de résoudre un problème (potentiel).
Je n'ai pas d'exemple sur moi en ce moment, mais dans certains cas, laisser NHibernate utiliser les propriétés de «porte d'entrée» qui imposent également des relations (en particulier bidi) conduit à des bogues.
Quelles sont les meilleures solutions?
Actuellement, je, sur une propriété par propriété base, créer une « porte arrière » juste pour NHibernate:
public virtual int Blah {get {return _Blah;} set {/*enforces BR's*/}}
protected virtual int _Blah {get {return blah;} set {blah = value;}}
private int blah;
J'ai montré ci-dessus en C# 2 (pas de propriétés par défaut) pour montrer comment cela se nous fondamentalement 3 couches de, ou vues, à bla !!! Bien que cela fonctionne certainement, cela ne semble pas idéal car cela nécessite que le BL fournisse une interface (publique) pour l'application en général, et une autre interface (protégée) pour la couche d'accès aux données. Il y a un problème supplémentaire: À ma connaissance, NHibernate ne vous permet pas de faire la distinction entre le nom de la propriété dans le BL et le nom de la propriété dans le modèle d'entité (c'est-à-dire le nom que vous utilisez lorsque vous requête, par exemple via HQL - chaque fois que vous donnez à NHibernate le nom (chaîne) d'une propriété). Cela devient un problème quand, au début, les BR pour certaines propriétés Blah ne posent aucun problème, donc vous vous référez à cela dans votre mapping O/R ... mais plus tard, vous devez ajouter quelques BR qui deviennent un problème, donc Ensuite, vous devez modifier votre mappage O/R pour utiliser une nouvelle propriété _Blah, qui casse toutes les requêtes existantes en utilisant "Blah" (problème courant de programmation par chaînes).
Est-ce que quelqu'un a résolu ces problèmes ?!
On ne sait pas pourquoi vous ne pouvez pas empêcher des données non valides d'entrer dans votre base de données. Je ne pense pas qu'il existe une solution de contournement général pour ce scénario (indépendamment du fait que NHibernate soit impliqué ou non). Vous pouvez peut-être constamment interroger la base de données à la recherche de données non valides, puis tenter de la corriger avant que NHibernate ne tente de la charger. –
Juste trouvé une discussion connexe: http://stackoverflow.com/questions/129773/nhibernate-map-to-fields-or-properties – apollodude217
@Michael: Bonne question/commentaire.Généralement, il s'agit d'une application héritée où les données préexistantes ne répondent pas aux exigences de l'entreprise (je sais que nous devrions les nettoyer) ou lorsqu'une autre application héritée permet aux mauvaises données d'entrer. – apollodude217