2009-11-19 2 views
0

Je l'extrait de code de code suivant:Comment insérer un objet détaché, qui peut déjà exister dans la base de données en utilisant NHibernate?

using (var scope = DataAccessPortal.DataContext(DB.Main).OpenStatementScope()) 
using (var transaction = scope.BeginTransaction()) 
{ 
    // Several other database operations. 
    if (scope.ExistsById(obj.GetType(), obj.Id)) 
    { 
    scope.Update(obj); 
    } 
    else 
    { 
    scope.Insert(obj); 
    } 
    transaction.Commit(); 
} 

scope et transaction sont des couches minces abstraites autour de la session NHibernate et objets transaction respectivement, ExistsById cartes à la requête HQL pour vérifier si l'ID donnée se trouve dans la base de données, Update et Insert correspondent aux opérations de session respectives.

Le but du code est de mettre à jour plusieurs objets dans la base de données, puis de mettre à jour un objet dans la base de données, qui peut déjà être trouvé - le code de mise à jour ou d'insertion.

Je n'aime pas le code de mise à jour ou d'insertion, car il donne deux allers-retours à la base de données. Est-il possible d'accomplir la même tâche avec un seul aller-retour en utilisant NHibernate?

Mes contraintes sont:

  • La base de données est sans procédures stockées prédéfinies. Si NHibernate permet d'en créer un dynamiquement indépendamment de DB, alors bien (comment ???), sinon utiliser une procédure stockée n'est pas une option.
  • Les chances sont que l'objet existe déjà dans la base de données, donc je pourrais juste faire une mise à jour, attraper l'exception si l'objet n'existe pas, puis réessayer avec Insert. Cependant, le code de mise à jour ou d'insertion fait partie d'une transaction plus importante. Donc, échouer échoue également la transaction, ce qui signifie que je devrai réessayer toute la transaction et pas seulement le morceau de code de mise à jour ou d'insertion. Je ne suis pas sûr que ce soit plus préférable à la situation actuelle.

Répondre

1

Vous aurez besoin d'un aller-retour DB dans tous les cas. Une session NHibernate agit comme un cache côté client qui maintient l'objet métier et la base de données synchronisés. Ainsi, si vous détachez puis réattachez un objet, la session n'a d'autre choix que de revérifier la base de données par rapport à l'objet. Il n'y a pas d'autre moyen, si vous y réfléchissez pendant une seconde ...

Habituellement, cela se fait avec les sessions refresh() méthode comme ceci (pseudo-code):

ISession session = GetSession(); 
session.Refresh(obj); 
session.DoSomething(); 

Que vous ayez une sorte de la façade ou de l'emballage autour de cela n'a pas d'importance. Le modèle global reste le même: Vous devez vérifier la base de données avant de pouvoir faire quelque chose ...

Questions connexes