2010-02-07 6 views
2

J'essaie de travailler efficacement avec les entités parent & enfant (post &). Un exemple du code peut être vu ici: http://gist.github.com/297464Retour efficace des enregistrements parent et enfant avec NHiberate

En utilisant les résultats suivants dans moins de 10 entités Post distinctes si l'un de Post contient plus de 1 tag.

var posts = session 
    .CreateCriteria<Post>() 
    .SetMaxResults(10) 
    .SetFetchMode("Tags", FetchMode.Eager) 
    .List<Post>(); 

Si je supprime la ligne .SetFetchMode ci-dessus, je reçois les 10 dossiers que je suis à la recherche, mais toutes les entités de Tag sont interrogés puis filtré en mémoire.

Il me semble que je devrais être capable d'ordonner à NHiberate de passer une liste de PostIds ou de faire une jointure. Je suis assez nouveau à NHiberate donc il est tout à fait possible que je vais complètement à tort.

Merci,
Scott

+0

pourrait ne pas affecter ce cas particulier, mais vous avez inverse = « true » sur la collection Tags, mais l'autre côté (de la collection Tag des postes) est commenté. Vous ne voulez que l'inverse du côté qui ne possède pas la collection. –

Répondre

2

Le problème est que setMaxResults n'est pas appliqué au nombre d'entités racine retournée de la requête, il est traduit en un TOP T-SQL (dans le cas de SqlServer), qui est appliqué au résultat d'une requête de jointure. Comme il y a une ligne dans le jeu de résultats pour chaque enfant d'une entité racine, le TOP n'aura pas l'effet désiré.

Pour atteindre une limite au nombre d'entités racine, vous pouvez utiliser une requête de jointure avec une sous-requête qui contient la limite SetMaxResults.

// Select the ids of the first ten posts 
var subquery = DetachedCriteria.For<Post>() 
    .SetMaxResults(10) 
    .SetProjection(Projections.Property("Id")); 

// Do a join query with posts and tags, for the posts who's ids are 
// in the result of the subquery 
var posts = session.CreateCriteria<Post>() 
    .SetFetchMode("Tags", FetchMode.Join) 
    .Add(Subqueries.PropertyIn("Id", subquery)) 
    .SetResultTransformer(Transformers.DistinctRootEntity) 
    .List<Post>(); 
+0

Merci pour le conseil. C'est beaucoup plus proche de ce que j'essayais d'accomplir. Malheureusement, il renvoie un brut par tag, mais le résultat final est maintenant en ligne avec ce que j'espérais accomplir. En fin de compte, je pense que je vais juste laisser les Tags être paresseux chargés (et mis en cache), mais il est bon de savoir que c'est une option. Merci! –

+0

Les "Tags" dans le code sont une chaîne magique. Y a-t-il un moyen d'éviter d'avoir les chaînes magiques et de pouvoir profiter du "renommer" dans les outils de refactoring? –

+0

Jetez un coup d'œil à http://code.google.com/p/nhlambdaextensions/ –

Questions connexes