2008-12-19 4 views
3

J'écris une application Web à l'aide de Castle ActiveRecord, et je reçois cette exception chaque fois que j'essaie d'accéder à une liste d'objets connexes chargés paresseusement. Voici mon code:Aide avec l'exception ActiveRecord "Impossible d'initialiser paresseusement une collection - aucune session"

 using(new SessionScope()) 
     { 
      foreach (var field in eventObj.RegistrationFields) 
      { 
       //Do something with the field here... 
      } 
     } 

La propriété RegistrationFields ressemble à ceci:

[HasMany(Inverse = true, Lazy = true)] 
    public IList<EventRegistrationField> RegistrationFields { get; set; } 

L'exception se produit lorsque les "eventObj.RegistrationFields" est accessible pour la boucle foreach. J'ai également veillé à définir l'attribut isweb = "true" dans mes paramètres de configuration activeRecord. Est-ce que quelqu'un sait pourquoi cela arriverait? Voici ma config:

<connectionStrings> 
    <add name="main" connectionString="Data Source=localhost\SQLEXPRESS;Initial Catalog=EventScheduler;Integrated Security=SSPI"/> 
</connectionStrings> 
<activerecord isWeb="true"> 
    <config> 
    <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/> 
    <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect"/> 
    <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/> 
    <add key="hibernate.connection.connection_string_name" value="main"/> 
    </config> 
</activerecord> 

Répondre

6

Je pense que vous êtes confus au sujet des sessions. RegistrationFields est une propriété paresseuse de eventObj. C'est la session chargée eventObj qui serait chargée de charger RegistrationFields. Vous ouvrez explicitement une nouvelle session en utilisant new SessionScope(), ce qui crée une nouvelle session à laquelle eventObj n'est pas lié; par conséquent, il n'y a pas de session propriétaire pour obtenir les données. Même si la session d'origine est toujours active, l'appel new SessionScope() imbrique une nouvelle session et masque l'ancienne où elle ne peut pas être vue jusqu'à ce que Dispose() soit appelée sur la portée actuelle. Les objets ne seront pas automatiquement attachés à la session en cours. C'est le comportement attendu de NHibernate.

On dirait que vous essayez de faire une session par unité de travail, ce qui est bien, mais le chargement des objets et la résolution de tous ces objets paresseux doit se faire dans cette unité de travail.

Vous pouvez essayer de passer en session par requête (voir les documents Castle pour savoir comment y arriver) et abandonner la création de SessionScope. Cela gardera vos objets en vie pendant la durée d'une demande de page (ce qui est aussi loin que toute collection paresseuse devrait vivre dans une application Web). Vous devez cependant savoir que dans ce scénario, toute modification apportée à un objet persistant sera écrite dans la base de données lors du vidage de la session (en fait, vous devez traiter une modification de l'état d'un objet persistant comme modification du sous-jacent données comme si elles étaient la même opération - alors vous ne pouvez pas vous tromper).

Questions connexes