2015-07-16 1 views
0

J'ai une table comme siNHibernate Groupement de requête

Id | Ref | Field1 
1  Myles1  Blah 
2  Myles1  Rubarb 
3  Myles2  Custard 
4  Ted  Cheese 

Je veux l'interroger via une session NHibernate afin que la première ligne pour chaque Ref contenant une chaîne de recherche donnée est retournée, donc avec un terme de recherche de 'Myles' le jeu de résultats serait

Id | Ref | Field1 
1  Myles1  Blah 
3  Myles2  Custard 

mapping Fluent comme si

public class EntityClassMap : ClassMap<Entity> 
{ 
    public EntityClassMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.Ref); 
     Map(x => x.Field1);   
    } 
} 
+0

Quelle est la « Première rangée »? est-ce important? –

+0

La première ligne signifiant la première ligne de chaque groupe avec un hit sur la recherche ref. En fait, dans ce cas, il n'est pas nécessaire d'être le premier tant que je ne suis en ligne que pour chaque réf. –

+0

Les lignes d'une base de données relationnelle n'ont pas d'ordre naturel, donc il n'y a pas de "première ligne" jusqu'à ce que vous décidiez commander dans la requête. –

Répondre

1

Il y a une descri détaillée ption comment les requêtes complexes (avec HAVING, GROUP BY) nous pouvons faire: Query on HasMany reference

Dans le cas, nous aimerions savoir ces entités, qui ont le Min (Id) regroupés par Ref, nous besoin subquery. Il pourrait ressembler à ceci:

// alias for inner query 
MyEntity inner = null; 
// this alias is for outer query, and will be used in 
// inner query as a condition in the HAVING clause 
MyEntity outer = null; 

var minIdSubquery = QueryOver.Of<MyEntity>(() => inner) 
    .SelectList(l => l 
     .SelectGroup(() => inner.Ref) // here we GROUP BY 
     .SelectMin(() => inner.Id) 
    ) 
    // HAVING to get just Min(id) match 
    .Where(Restrictions.EqProperty(
     Projections.Min<MyEntity>(i => i.Id), 
     Projections.Property(() => outer.Id) 
    )); 

// outer query 
var query = session.QueryOver<MyEntity>(() => outer) 
    .WithSubquery 
    // we can now use EXISTS, because we applied match in subquery 
    .WhereExists(minIdSubquery); 

Voir plus dans la doc 16.8. Subqueries ou here

+0

Je pense qu'il n'y a pas de one-to-many en place. Un simple Min (Field1), Grouper par Ref, Avoir blah serait suffisant. –

+0

Correct, il n'y a pas un à plusieurs ... ajoutera la classe de mapping à la question. Pouvez-vous donner un exemple s'il vous plaît Stefan? Merci –