2009-11-03 8 views
3

J'essaie d'ordonner une requête Linq à NHibernate par la somme de ses enfants.Linq-to-NHibernate OrderBy ne fonctionne pas

session.Linq<Parent>().OrderBy(p => p.Children.Sum(c => c.SomeNumber)).ToList() 

Cela ne semble pas fonctionner. Lors de l'examen NHProf, je peux voir qu'il passe commande auprès de Parent.Id. J'ai pensé que peut-être il retournait les résultats et les commande en dehors de SQL, mais si j'ajoute un .Skip (1) .Take (1) à la requête Linq, il commande encore par Parent.Id.

J'ai essayé de le faire avec une liste en mémoire et cela fonctionne juste bien.

Est-ce que je fais quelque chose de mal, ou est-ce un problème avec Linq à NHibernate?

Je suis sûr que je pourrais toujours retourner la liste, puis faire les opérations sur eux, mais ce n'est pas une solution de contournement idéale, parce que je ne veux pas retourner tous les enregistrements.

Répondre

2

Pour commander une requête par une valeur d'agrégation, vous devez utiliser un groupe par requête. Dans votre exemple, vous devez utiliser un 'group by' avec une jointure.

Le equivelant SQL serait quelque chose comme:

select id, sum(child.parentid) as childsum from dbo.Parent 
inner join child on 
parent.id= child.parentid 
group by id 
order by childsum desc 

Si seulement Linq2NH pourrait faire pour nous ... mais il ne peut pas malheureusement. Vous pouvez le faire dans HQL aussi longtemps que vous êtes d'accord pour obtenir l'ID, et la somme de retour, mais pas l'ensemble de l'objet.

J'ai lutté avec Linq2NH pendant des mois avant de l'abandonner. C'est lent, ne supporte pas le cache de second niveau et ne supporte que les requêtes TRES basiques. (au moins quand je l'ai abandonné il y a 6 mois - ça a peut-être marché à pas de géant!) C'est bien si vous faites une simple application faite maison. Si votre application est encore plus complexe, abandonnez-la et passez un peu de temps à apprendre à connaître HQL: un peu plus difficile à comprendre mais beaucoup plus puissant.

+0

La raison pour laquelle je ne veux pas utiliser HQL est de refactoriser. La recréation n'attrape pas les chaînes HQL. C'est la même raison pour laquelle j'utilise FluentNHibernate au lieu de fichiers .hbm. J'ai besoin de récupérer tout l'objet, je veux juste qu'il soit ordonné par un agrégat. Je peux le faire très bien en SQL, donc HQL le supporte probablement aussi, si j'ai vraiment besoin de suivre cette route. Je ne suis pas sûr de la performance de Linq2NH. Cela semble assez rapide maintenant. Peut-être que la version 1.0 a quelques améliorations. Il est supposé passer la plupart des tests de requête NHibernate (donc j'ai lu, même pas sûr de ce qu'ils sont). –

+0

http://hiberlog.wordpress.com/2009/02/16/lambda-expressions-extension-methods-and-nhibernate/ Voici une page que j'ai mise en signet plus tôt aujourd'hui à propos de l'utilisation des méthodes d'extension pour taper de façon stricte des requêtes de critères. Je ne l'ai pas encore lu, mais vous pourriez trouver cela intéressant, car vous êtes préoccupé par les requêtes fortement typées. Désolé je ne pourrais pas être plus utile! – reach4thelasers

+0

J'ai déjà utilisé NHLambdaExtensions auparavant. http://code.google.com/p/nhlambdaextensions/ Cela a plutôt bien fonctionné, mais je n'aime vraiment pas les requêtes de critères. Je préfère utiliser HQL et faire des tests unitaires pour vérifier les erreurs. –