2010-04-19 8 views
1

Je vais avoir un cas du lundi ...Utilisation de NHibernate pour sélectionner des entités en fonction de l'activité des entités enfants

je dois sélectionner les messages de blog basé sur l'activité récente dans la collection des commentaires du poste (un message a List<Comment> propriété et de même, un commentaire a une propriété de publication, établissant la relation.Je ne veux pas montrer le même poste deux fois, et j'ai seulement besoin d'un sous-ensemble des entités, pas tous les postes

était de saisir tous les messages qui ont des commentaires, puis les commander sur la base du commentaire le plus récent.Pour que cela fonctionne, je suis sûr que je devrais limiter les commentaires pour chaque poste au premier/plus récent commentaire. d simplement prendre e top 5 (ou quel que soit le nombre maximum de résultats que je veux passer dans la méthode).

Seconde pensée serait de saisir tous les commentaires, commandés par CreatedOn, et filtre donc il n'y a qu'un seul commentaire par message. Ensuite, retournez les messages les plus importants. Cela semble être la même chose que la première option, juste en passant par la porte arrière. J'ai une option de requête moche, deux j'ai travaillé avec un peu de LINQ sur le côté pour le filtrage, mais je sais qu'il y a une façon plus élégante de le faire en utilisant l'API NHibernate. En espérant voir de bonnes idées ici.

EDIT: Voici ce qui fonctionne pour moi jusqu'à présent. Bien que cela fonctionne, je suis sûr qu'il ya une meilleure façon de le faire ...

// get all comments ordered by CreatedOn date 
var comments = Session.CreateCriteria(typeof(Comment)).AddOrder(new Order("CreatedOn", false)).List<Comment>(); 
var postIDs = (from c in comments select c.ParentPost.ID).Distinct(); 

// filter the comments 
List<Post> posts = new List<Post>(); 
foreach(var postID in postIDs) 
{ 
    var post = Get(postID); // get a Post by ID 
    if(!posts.Contains(post)) // this "if" is redundant due to the Distinct filter on the PostIDs collection 
    { 
     posts.Add(post); 
    } 
} 

return posts; 
+0

Ajouté le plus à ma réponse –

Répondre

2

est d'utiliser la syntaxe NHibernate.LambdaExtensions mais devrait être facilement transformé en un critère de requête standard ou d'une requête HQL.

var query1 = DetachedCriteria.For<Post>() 
    .CreateCriteria<Post>(x => x.Comments) 
    .Add<Comment>(x => x.CreatedDate >= DateTime.Now.AddDays(-5)); 

query1.GetExecutableCriteria(session).List<T>(); 

Vous voudrez aussi probablement charger avec impatience la collection et définissez vos limites à ce applicable à ce que vous voulez éviter de tirer sur toute la base arrière et la condition de la requête N + 1 de itérer sur une liste chargée paresseusement.

La première étape à résoudre tout type de requête complexe avec NHibernate est de commencer à partir du SQL d'origine si vraiment nous devons commencer avec quelque chose comme

Select P.* 
From Post P 
Where P.PostID Exists (
    Select P1.PostID 
    From Posts P1 Inner Join Comments C ON (P1.PostID = C.PostID) 
    Where P1.PostID Exists (
     Select Top 5 C1.PostID, Count(*) as PostCount 
     From Comments C1 
     Group By C1.PostID 
     Order By PostCount DESC 
    ) 
    And C.CreateDate > Now - 5 days 
) 

Cela a été écrit à la main si cela est plus un approximation de la requête et devrait être en mesure de vous orienter dans le sens d'être en mesure de résoudre la requête. Avec quelques commentaires à ce sujet, je peux en ajouter plus sur la traduction à NH. De plus, ce dernier existant pourrait être abandonné dans la version finale de NH car je crois que la matrice de Post with Comments est comment NH chargera les entités avec impatience.

+0

C'est un début, mais je ne veux pas seulement les messages avec les commentaires des 5 derniers jours. J'ai besoin du top 5 des résultats de tous les messages avec des commentaires classés par leur commentaire le plus récent. L'application cible n'obtient pas beaucoup de trafic, donc s'il n'y a pas d'activité pendant x fois, aucun message n'apparaîtra du tout. – nkirkes

+0

Que voulez-vous dire par dessus? Les articles qui ont les commentaires les plus récents? –

+0

Oui, je n'ai besoin que de 5 messages uniques, mais 5 sont sélectionnés en fonction de l'âge de leur dernier commentaire. Donc, j'essaie de saisir le commentaire le plus récent pour chaque article, puis de commander les articles en fonction de la date du commentaire (en supposant que nous ne regardons que le commentaire le plus récent pour un article), puis prenez le top 5 des messages. Je sais comment obtenir le jeu de résultats limité dont j'ai besoin. Je me bats avec la façon de sélectionner élégamment une collection de messages en fonction de l'âge du commentaire le plus récent de chaque message. – nkirkes

Questions connexes