2009-08-05 6 views
0

J'ai une GridView liée à un ObjectDataSource en utilisant la pagination. La pagination fonctionne correctement, sauf que l'ordre de tri change en fonction de la page du résultat affichée. Cela entraîne la réapparition des éléments sur les pages suivantes parmi d'autres problèmes. J'ai tracé le problème à mon DAL, qui lit une page à la fois et le trie ensuite. Évidemment, le tri va changer à mesure que la taille de l'ensemble de résultats change. Y a-t-il une amélioration à cet algorithme? Je voudrais utiliser un lecteur de données si possible:Problème: Tri pour les modifications GridView/ObjectDataSource en fonction de la page

[System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)] 
    public static WordsCollection LoadForCriteria(string sqlCriteria, int maximumRows, int startRowIndex, string sortExpression) 
    { 
     //DEFAULT SORT EXPRESSION 
     if (string.IsNullOrEmpty(sortExpression)) sortExpression = "OrderBy"; 
     //CREATE THE DYNAMIC SQL TO LOAD OBJECT 
     StringBuilder selectQuery = new StringBuilder(); 
     selectQuery.Append("SELECT"); 
     if (maximumRows > 0) selectQuery.Append(" TOP " + (startRowIndex + maximumRows).ToString()); 
     selectQuery.Append(" " + Words.GetColumnNames(string.Empty)); 
     selectQuery.Append(" FROM sw_Words"); 
     string whereClause = string.IsNullOrEmpty(sqlCriteria) ? string.Empty : " WHERE " + sqlCriteria; 
     selectQuery.Append(whereClause); 
     selectQuery.Append(" ORDER BY " + sortExpression); 
     Database database = Token.Instance.Database; 
     DbCommand selectCommand = database.GetSqlStringCommand(selectQuery.ToString()); 
     //EXECUTE THE COMMAND 
     WordsCollection results = new WordsCollection(); 
     int thisIndex = 0; 
     int rowCount = 0; 
     using (IDataReader dr = database.ExecuteReader(selectCommand)) 
     { 
      while (dr.Read() && ((maximumRows < 1) || (rowCount < maximumRows))) 
      { 
       if (thisIndex >= startRowIndex) 
       { 
        Words varWords = new Words(); 
        Words.LoadDataReader(varWords, dr); 
        results.Add(varWords); 
        rowCount++; 
       } 
       thisIndex++; 
      } 
      dr.Close(); 
     } 
     return results; 
    } 

Répondre

0

J'ai trouvé une solution à ce problème en lisant MSDN. L'astuce consiste à exécuter la requête complète et à renvoyer uniquement le sous-ensemble intéressant, de sorte que le tri est toujours cohérent. La procédure, cependant, ne fonctionne qu'avec SQL 2005.

[System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)] 
    public static WordsCollection LoadForCriteria(string sqlCriteria, int maximumRows, int startRowIndex, string sortExpression) 
    { 
     //DEFAULT SORT EXPRESSION 
     if (string.IsNullOrEmpty(sortExpression)) sortExpression = "OrderBy"; 
     //CREATE THE DYNAMIC SQL TO LOAD OBJECT 
     StringBuilder selectQuery = new StringBuilder(); 
     selectQuery.Append("SELECT "); 
     selectQuery.Append(Words.GetColumnNames(string.Empty)); 
     selectQuery.Append(" FROM ("); 
     selectQuery.Append("SELECT "); 
     selectQuery.Append(Words.GetColumnNames(string.Empty)); 
     selectQuery.Append(", ROW_NUMBER() OVER (ORDER BY " + sortExpression + ") AS RowRank"); 
     selectQuery.Append(" FROM sw_Words) AS WordsWithRowNumbers"); 
     selectQuery.Append(" WHERE RowRank >" + startRowIndex.ToString() + " AND " + "RowRank <=" + (startRowIndex + maximumRows).ToString()); 
     string whereClause = string.IsNullOrEmpty(sqlCriteria) ? string.Empty : " AND " + sqlCriteria; 
     selectQuery.Append(whereClause); 
     Database database = Token.Instance.Database; 
     DbCommand selectCommand = database.GetSqlStringCommand(selectQuery.ToString()); 
     //EXECUTE THE COMMAND 
     WordsCollection results = new WordsCollection(); 
     int rowCount = 0; 
     using (IDataReader dr = database.ExecuteReader(selectCommand)) 
     { 
      while (dr.Read()) 
      { 
       Words varWords = new Words(); 
       Words.LoadDataReader(varWords, dr); 
       results.Add(varWords); 
       rowCount++; 
      } 
      dr.Close(); 
     } 
     return results; 
    }