2011-01-06 16 views
6

Ho questo metodo Repository che utilizza QueryOver APIProblemi con NHibernate distinto e paging

public IList<Message> ListMessagesBy(string text, IList<Tag> tags, int pageIndex, out int count, out int pageSize) 
    { 
     pageSize = 10; 
     var likeString = string.Format("%{0}%", text); 
     var query = session.QueryOver<Message>() 
      .Where(Restrictions.On<Message>(m => m.Text).IsLike(likeString) || 
      Restrictions.On<Message>(m => m.Fullname).IsLike(likeString)); 

     if (tags.Count > 0) 
     { 
      var tagIds = tags.Select(t => t.Id).ToList(); 
      query 
       .JoinQueryOver<Tag>(m => m.Tags) 
       .WhereRestrictionOn(t => t.Id).IsInG(tagIds) 
       .TransformUsing(Transformers.DistinctRootEntity); 
     }       

     count = 0; 
     if(pageIndex < 0) 
     { 
      count = query.ToRowCountQuery().FutureValue<int>().Value; 
      pageIndex = 0; 
     } 
     return query.OrderBy(m => m.Created).Desc.Skip(pageIndex * pageSize).Take(pageSize).List(); 
    } 

Ho provato entrambe

.RootCriteria.SetResultTransformer(new DistinctEntityRootTransformer()) 

avvita

.TransformUsing(Transformers.DistinctRootEntity); 

e

tanto del conteggio totale (restituisce il risultato non distinto) e il paging effettivo (Salta/Scatta)

Come posso risolvere questo?

Grazie in anticipo, Anders

risposta

3

provare qualcosa di simile

public IPagedList<Client> Find(int pageIndex, int pageSize) 
{ 
    Client clientAlias = null; 

    var query = Session.QueryOver<Client>(() => clientAlias) 

     .Select(
      Projections.Distinct(
       Projections.ProjectionList() 
        .Add(Projections.Property<Client>(x => x.Id).As("Id")) 
        .Add(Projections.Property<Client>(x => x.Name).As("Name")) 
        .Add(Projections.Property<Client>(x => x.Surname).As("Surname")) 
        .Add(Projections.Property<Client>(x => x.GivenName).As("GivenName")) 
        .Add(Projections.Property<Client>(x => x.EmailAddress).As("EmailAddress")) 
        .Add(Projections.Property<Client>(x => x.MobilePhone).As("MobilePhone")) 
      ) 
     ) 
     .TransformUsing(Transformers.AliasToBean<Client>()) 

     .OrderBy(() => clientAlias.Surname).Asc 
     .ThenBy(() => clientAlias.GivenName).Asc; 

    var count = query 
     .ToRowCountQuery() 
     .FutureValue<int>(); 

    return query 
     .Take(pageSize) 
     .Skip(Pagination.FirstResult(pageIndex, pageSize)) 
     .List<Client>() 
     .ToPagedList(pageIndex, pageSize, count.Value); 
} 
+3

una spiegazione del perché/come la vostra risposta è corretta avrebbe potuto essere utile, invece di 'Qui ci sono le Codez' – sweaver2112

1

ho avuto un problema con questo pure. Innanzitutto il Distinct funziona, ma solo dopo che è stato chiamato il metodo QueryOver.List.ToList(), quindi query.skip non funzionava correttamente, cercava i duplicati, creava l'elenco, quindi riduceva la quantità paginata a causa dei duplicati .

cosa più semplice che ho trovato per fare era .. è sufficiente creare un elenco di ID univoci, poi fare la vostra impaginazione sul Ids stessi ..

Poi impostare il risultato che si può semplicemente eseguire un Id e recuperare il ID solo nel set di risultati ID appena impaginato.

//Create your query as usual.. apply criteria.. do what ever you want. 

//Get a unique set of ids from the result set. 
var idList = query. 
.Select(x => x.Id) 
.List<long>().Distinct().ToList(); 

//Do your pagination here over those ids 
List<long> pagedIds = idList.Skip(0).Take(10).ToList(); 

//Here what used to be non distinct resultset, now is.. 
List<T> resultquery.Where(() => 
item.Id.IsIn(pagedIds)) 
.List<Person>() 
.ToList(); 

Un ringraziamento speciale a .. https://julianjelfs.wordpress.com/2009/04/03/nhibernate-removing-duplicates-combined-with-paging/