2010-09-13 24 views
1

Je développe une application (asp.net mvc) et j'utilise ISession par requête (dans globa.asax j'utilise Bind et Unbind dans les événements Begin_Request et End_Request). Tout fonctionne bien mais parfois (certaines requêtes) je n'ai pas besoin d'utiliser une ISession (une connexion avec la base de données). Je voudrais savoir s'il y a un moyen d'ouvrir un ISession seulement quand j'ai besoin et de faire l'entrée ISession dans toutes les demandes de processus (à partager avec tous les dépôts et un contexte de transaction unique)?ISession par Requête (Seulement si nécessaire)

Je suis développeur et site d'enchères de sou et mon serveur aura beaucoup de demandes par seconde et parfois je n'ai pas besoin de la connexion, je vais utiliser un cache.

Merci

Vive

Répondre

2

Il convient de noter que l'ouverture d'une session n'implique pas l'ouverture d'une connexion à la base de données. Comme indiqué dans this article, le coût d'ouverture d'une session est extrêmement faible. Donc, en général, je ne m'inquiéterais pas des demandes d'ouverture de session quand ils n'en ont pas besoin; Essentiellement, vous venez de créer un objet très léger.

+0

Je ne savais pas à ce sujet, peut-être qu'il n'y a pas de problème. Merci! –

+0

Je peux fortement recommander NHProf si vous avez besoin d'avoir une vue d'oiseau de ce qui se passe sous les couvertures avec NHibernate. Si rien d'autre, cela devrait aider à vérifier qu'aucune interaction de base de données n'a lieu dans les sessions emtpy. – DanP

+0

Salut @DanP, Oui, j'utilise NHProf pour voir plus de détails, et vraiment quelques pages me donnent une session vide. Je vais implémenter le chronomètre pour la vente aux enchères de centimes et chaque seconde mon application aura une demande. Tout comme vous recommandez et article Ayenge, ce ne sera pas un problème = D. Merci –

2

Vous pouvez utiliser un ActionFilter pour le faire. En voici un que j'utilise pour faire exactement ce que vous décrivez.

public class UsingNhibernate : ActionFilterAttribute { 
    private ISession nhSession; 
    public override void OnActionExecuting(ActionExecutingContext filterContext) { 
     nhSession = NHHelper.OpenSession(); 
     nhSession.BeginTransaction(); 
     // set an accessible reference to your nhSession for access from elsewhere 
     // ((ApplicationController)filterContext.Controller).nHSession = nhSession; is what I do 
     base.OnActionExecuting(filterContext); 
    } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) { 
     try { 
      if (filterContext.Exception == null && nhSession != null && nhSession.Transaction.IsActive) 
       nhSession.Transaction.Commit(); 
      else if (nhSession != null && nhSession.Transaction.IsActive) 
       nhSession.Transaction.Rollback(); 
     } catch (Exception ex) { 
      if (nhSession != null && nhSession.Transaction.IsActive) 
       nhSession.Transaction.Rollback(); 
      nhSession.Dispose(); 
      throw; 
     } 
     nhSession.Dispose(); 
     base.OnActionExecuted(filterContext); 
    } 
} 

Sur chaque action du contrôleur approprié (ou même au niveau du contrôleur pour appliquer à toutes les actions) vous suffit d'ajouter le filtre d'action UsingNhibernate comme ceci:

[UsingNhibernate] 
public ActionResult SaveSystemSetting(SystemAdminVM item) {