2011-01-06 22 views
6

que tiene este método de repositorio que utiliza la API QueryOverProblema con NHibernate distintas y paginación

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(); 
    } 

He intentado tanto

.TransformUsing(Transformers.DistinctRootEntity); 

y

.RootCriteria.SetResultTransformer(new DistinctEntityRootTransformer()) 

tornillos hacia arriba tanto en el recuento total (devuelve resultado ninguno distinto) y la paginación real (Saltar/Tomar)

¿Cómo puedo solucionar esto?

Gracias de antemano, Anders

Respuesta

3

intentar algo como esto

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 explicación de por qué/cómo su respuesta es correcta podría haber sido útil, en lugar de sólo 'aquí están los Codez' – sweaver2112

1

tuve un problema con esto también. En primer lugar, Distinct funciona, pero solo después de que se invocó el método QueryOver.List.ToList(), por lo que query.skip no funcionaba correctamente, buscaba los duplicados, creaba la lista y luego reducía mi cantidad de páginas debido a los duplicados .

cosa más fácil que encontré para hacer fue .. basta con crear una lista de identificadores únicos en primer lugar, a continuación, hacer su paginación de los propios identificadores ..

A continuación, en el set de su resultado sólo tiene que realizar una identificación y recuperar el identificadores solo en el conjunto de resultados de identificación recién paginado.

//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 agradecimiento especial a .. https://julianjelfs.wordpress.com/2009/04/03/nhibernate-removing-duplicates-combined-with-paging/

Cuestiones relacionadas