2010-09-30 9 views
1

J'ai un grand besoin d'aide.Les critères Nhibernate font une requête dynamique et obtiennent le nombre de lignes

Je fais requête dynamique en utilisant des critères:

ICriteria query = session.CreateCriteria(typeof(Employee)); 

if (searchOptions.FirstName != null) 
{ 
    query.Add(Expression.Eq("FirstName", searchOptions.FirstName)); 
} 

if (!searchOptions.LastName != null) 
{ 
    query.Add(Expression.Eq("LastName", searchOptions.LastName)); 
} 

if (searchOptions.PhoneNumber != null) 
{ 
    query.CreateCriteria("PhoneNumbers") 
    .Add(Expression.Like("Number", searchOptions.PhoneNumber + "%")); 
} 

Après cela, je dois avoir à la fois total Nombre de lignes et Pagination.

Pagination:

query.SetFirstResult(0).SetMaxResults(8); 

pour rowcount:

query.SetProjection(Projections.RowCountInt64()); 

Comment puis-je exécuter à la fois dans une seule requête soit en utilisant une multicritère ou autre chose.

Aidez s'il vous plaît!

Répondre

5

Vous pouvez voir ma réponse dans nhibernate 2.0 Efficient Data Paging DataList Control and ObjectDataSource.

code

à nouveau:

protected IList<T> GetByCriteria(
     ICriteria criteria, 
     int pageIndex, 
     int pageSize, 
     out long totalCount) 
    { 
     ICriteria recordsCriteria = CriteriaTransformer.Clone(criteria); 

     // Paging. 
     recordsCriteria.SetFirstResult(pageIndex * pageSize); 
     recordsCriteria.SetMaxResults(pageSize); 

     // Count criteria. 
     ICriteria countCriteria = CriteriaTransformer.TransformToRowCount(criteria); 

     // Perform multi criteria to get both results and count in one trip to the database. 
     IMultiCriteria multiCriteria = Session.CreateMultiCriteria(); 
     multiCriteria.Add(recordsCriteria); 
     multiCriteria.Add(countCriteria); 
     IList multiResult = multiCriteria.List(); 

     IList untypedRecords = multiResult[0] as IList; 
     IList<T> records = new List<T>(); 
     if (untypedRecords != null) 
     { 
      foreach (T obj in untypedRecords) 
      { 
       records.Add(obj); 
      } 
     } 
     else 
     { 
      records = new List<T>(); 
     } 

     totalCount = Convert.ToInt64(((IList)multiResult[1])[0]); 

     return records; 
    } 

Il clone vos critères d'origine deux fois: un critère qui renvoient les enregistrements de la page et un critère de nombre total d'enregistrements. Il utilise également IMultiCriteria pour effectuer les deux appels de base de données en un seul aller-retour.

+0

Avez-vous testé cela pour performance? Est-ce que cela l'améliore réellement, et de combien? –

+0

Je vais répondre à ma propre question. La réponse courte, est-ce d'environ 25% -30% selon ayende. Voir http://ayende.com/Blog/archive/2009/04/27/nhibernate-futures.aspx –