Je me débats avec cela depuis un moment et je ne peux pas sembler comprendre ...
J'ai un Ce que je dois faire est de faire une requête pour un J'ai cette requête: P> blogpost code> classe, qui a une collection de Commentaires code> et chacun des commentaires a un champ
DatePosted code>. p>
blogpost code> et Retournez-le avec un
partiellement chargé de la collection CODE>, disons que tous les commentaires affichés le 1 août 2009. p>
BlogPost post = session.CreateCriteria<BlogPost>()
.Add(Restrictions.Eq("Id", 1))
.CreateAlias("Comments", "c")
.Add(Restrictions.Eq("c.DatePosted", new DateTime(2009, 8, 1)))
.UniqueResult<BlogPost>();
5 Réponses :
Tu ne fais rien vraiment mal - Hibernate ne fonctionne tout simplement pas de cette façon.
Si vous naviguez depuis le blogpost auprès des commentaires, Hibernate remplacera les commentaires basés sur la cartographie de l'association que vous avez spécifiée, Pas la requête que vous avez utilisée pour récupérer le blogpostost. Vraisemblablement votre cartographie fait juste une jointure
sur une colonne clé. Vous pouvez utiliser un filtre pour obtenir l'effet a > Vous cherchez. Mais je pense que cela va toujours aller chercher tous les commentaires, puis faire un post-filtre. P> Plus simplement, il suffit d'interroger pour ce que vous voulez: p> post.setComments(comments); //having already retreived the post elsewhere
NH ne fait jamais de filtrage post-filtrage.
Merci pour la réponse, je suppose que je comprends un peu pourquoi sa conception, mais j'aurais pensé qu'il y aurait une méthode intégrée pour permettre cela, votre solution fonctionne, mais ressemble à un peu de hack!
Mon problème est que la collection enfant est énorme si elle n'est pas filtrée (l'exemple que j'ai donné de postes et de commentaires était de protéger les noms de l'innocent!) Et il y a maintenant une façon de tirer toutes les données à chaque fois. p>
J'ai exécuté SQL Profiler à ce sujet et c'est toujours en train de tirer toutes les données.
Lorsque j'exécute le code suivant, la première requête effectue ce que vous attendez, juste l'un après le revient, mais dès que la deuxième requête est exécutée, deux requêtes vont à la base de données, le premier à récupérer les commentaires filtrés (Bingo!), et puis une seconde pour peupler la propriété Post.comments avec tous les commentaires, ce que j'essaie d'éviter! p> C'est très étrange, ce n'est pas comme je ' m Enumérant sur la liste Post.Comments, alors pourquoi est-ce que cela le remplit ?! Voici mes classes et maps: P> public class BlogPostMap : ClassMap<BlogPost>
{
public BlogPostMap()
{
Id(b => b.Id);
Map(b => b.Title);
Map(b => b.Body);
HasMany(b => b.Comments).KeyColumnNames.Add("BlogPostId");
}
}
public class CommentMap : ClassMap<Comment>
{
public CommentMap()
{
Id(c => c.Id);
Map(c => c.BlogPostId);
Map(c => c.Text);
Map(c => c.DatePosted);
}
}
public class BlogPost
{
public virtual int Id { get; set; }
public virtual string Title { get; set; }
public virtual string Body { get; set; }
public virtual IList<Comment> Comments { get; set; }
}
public class Comment
{
public virtual int Id { get; set; }
public virtual int BlogPostId { get; set; }
public virtual string Text { get; set; }
public virtual DateTime DatePosted { get; set; }
}
Utilisez le setsultTransformer. Voir ma réponse.
Je suis d'accord, je suis d'accord comme un hack de remplir manuellement la collection.
Vous pouvez utiliser un chargeur personnalisé à la place. Quelque chose comme ceci: p> En outre, vous pouvez utiliser SQL-requête si vous voulez plus de contrôle.
J'ai parfois été retiré pour écrire des chargeurs personnalisés lorsque je ne pouvais pas obtenir hibernate de générer la requête que je voulais. Quoi qu'il en soit, je ne sais pas pourquoi je ne pensais pas à ça en premier lieu. P> p>
Il y a un transformateur de résultat pour cela, voir La documentation.
Quote: P>
Notez que les collections de chatons tenues par les cas de chat renvoyé par le Les deux requêtes précédentes ne sont pas pré-filtré par les critères! Si vous souhaite récupérer les chatons que Faites correspondre les critères, vous devez utiliser
SETRESULTTRANSFORMER (CritèreUTIL.MAALYSTOENTYTYMAP) CODE>. P>
IList cats = sess.CreateCriteria(typeof(Cat)) .CreateCriteria("Kittens", "kt") .Add( Expression.Eq("Name", "F%") ) .SetResultTransformer(CriteriaUtil.AliasToEntityMap) .List();
Faites de la collection de commentaires paresseux, de sorte que Hibernate ne le récupère pas lorsque vous obtenez le blogpostost. Ensuite, utilisez un filtre sur la collection de commentaires.
comments = session.CreateFilter(blogPost.Comments, ... ).List();