Je crée une application de sondage dans laquelle j'ai un sondage qui contient une collection de pages. Chaque page aura une collection de questions et chaque question aura une collection d'options de réponse. Ma structure de classe ressemble à:Récupérer efficacement un objet avec des collections imbriquées à l'aide de NHibernate
public class Survey : Entity {
public IList<Page> Pages { get; set; }
}
public class Page : Entity {
public IList<Question> Questions { get;set; }
}
public class Question : Entity {
public IList<Option> Options { get; set; }
}
public class Option : Entity {}
La mise en correspondance pour chaque classe est:
<!-- mapping for ID and other properties excluded -->
<class name="Survey">
<bag name="Pages" generic="true" inverse="true">
<key column="SurveyId" />
<one-to-many class="Page" />
</bag>
<bag name="Questions" access="none">
<key column="SurveyId" />
<one-to-many class="Question" />
</bag>
</class>
<class name="Page">
<many-to-one name="Survey" column="SurveyId" />
<bag name="Questions" generic="true" inverse="true">
<key column="PageId" />
<one-to-many class="Question" />
</bag>
</class>
<class name="Question">
<many-to-one name="Page" column="PageId" />
<many-to-one name="Survey" column="SurveyId" />
<bag name="Options" generic="true" inverse="true">
<key column="QuestionId" />
<one-to-many class="Option" />
</bag>
</class>
<class name="AnswerOption">
<many-to-one name="Question" column="QuestionId" />
</class>
Je dois montrer toutes les questions sur une page si je commence avec l'objet de l'enquête et la boucle à travers les pages, articles et options. Cela provoque NHibernate à exécuter de nombreuses requêtes et je voudrais optimiser cela. Comment puis-je obtenir l'objet de sondage avec les collections imbriquées de la meilleure façon possible sans exécuter trop de requêtes?
C'est le code que j'ai en ce moment, mais il exécute encore beaucoup de requêtes:
var result = Session.CreateMultiQuery()
.Add(Session.CreateQuery("from Survey s inner join fetch s.Pages where s.Id = :id"))
.Add(Session.CreateQuery("from Survey s inner join fetch s.Question where s.Id = :id"))
.SetInt32("id", id)
.List();
IList list = (IList)result[0];
return list[0] as Survey;
J'ai aussi essayé requêtes futures mais ils ne contribuent pas à réduire le nombre de requêtes.
Des idées?
J'avais ajouté lazy = "false" à mon mapping sans chercher et cela n'a pas aidé. L'ajout de fetch a réduit les requêtes. Cependant, je ne veux pas modifier le mapping car je chercherais juste une question ou simplement l'objet de l'enquête et je n'aurais pas besoin des collections. Cela peut-il être fait en utilisant l'API HQL ou Criteria? –