2009-11-23 4 views
1

J'ai une autre post qui a abouti à cetteSQL Server Search, comment retourner le nombre total de lignes?

SELECT DISTINCT 
     a.ArticleID, 
     COUNT(*) AS KeywordMatch, 
     a.Headline, 
     a.ShortDescription, 
     a.CategoryID, 
     a.ArticleSectionImage, 
     a.DatePublished 
    FROM 
     Article a 
    JOIN SearchWords sw ON a.ArticleID = sw.ArticleID 
    WHERE 
     EXISTS 
     (
      SELECT 
       1 
      FROM 
       iter_charlist_to_tbl(@temp, ' ') s 
      WHERE 
       s.nstr = sw.SearchWord 
     ) 
     AND 
      a.ArticleState = 3 
    GROUP BY 
     a.ArticleID, a.Headline, a.ShortDescription, a.CategoryID, a.ArticleSectionImage, a.DatePublished 
    ORDER BY (KeywordMatch) DESC, (a.DatePublished) DESC 

Je me sers de ce long avec LINQ to SQL pour créer la pagination pour les utilisateurs. Le problème est que j'ai besoin de savoir combien d'enregistrements ma recherche a renvoyé (nombre total de lignes), pour afficher les flèches correctes pour l'utilisateur.

Ceci est mon Linq-to-SQL Query:

int iPageNum = pageNumber; 
    int iPageSize = (int)pageSize; 

    results = data.SearchArticles(searchString).Skip((iPageNum - 1) * iPageSize).Take(iPageSize).ToList(); 

Toutes les idées?

Mon Linq-to-SQL extrait-t-il tous les enregistrements de la base de données? ou crée-t-il une requête qui ne sélectionne que les enregistrements dont j'ai besoin? Comment puis-je pointer à la requête?

+0

Quel type de client écrivez-vous? Il y a une chance raisonnable qu'il y ait un composant de pagination déjà écrit que vous pouvez simplement utiliser. –

+0

J'ajoute la fonction de recherche à notre nouveau site "journal", petit. Donc je fais tout moi-même. – Patrick

Répondre

2

Une approche consiste à avoir deux requêtes: une qui renvoie un nombre, et une autre qui renvoie les données.

Vous pouvez les mettre tous les deux dans un SP avec plusieurs jeux de résultats pour éviter un aller-retour DB supplémentaire. J'explique un exemple de pagination de données (y compris en fournissant un compte) en détail dans mon livre: Ultra-Fast ASP.NET. Mon approche n'utilise pas LINQ (car elle ne supporte pas plusieurs ensembles de résultats), mais c'est aussi plus rapide.

Voici une requête qui devrait compter le nombre de lignes dans le résultat (non testé, mais il devrait être proche):

;WITH SearchArticles (aid, cnt, headline, descr, cid, img, datepub) as ( 
SELECT DISTINCT 
      a.ArticleID, 
      COUNT(*) AS KeywordMatch, 
      a.Headline, 
      a.ShortDescription, 
      a.CategoryID, 
      a.ArticleSectionImage, 
      a.DatePublished 
     FROM 
      Article a 
     JOIN SearchWords sw ON a.ArticleID = sw.ArticleID 
     WHERE 
      EXISTS 
      (
        SELECT 
         1 
        FROM 
         iter_charlist_to_tbl(@temp, ' ') s 
        WHERE 
         s.nstr = sw.SearchWord 
      ) 
      AND 
        a.ArticleState = 3  
     GROUP BY 
      a.ArticleID, a.Headline, a.ShortDescription, a.CategoryID, 
      a.ArticleSectionImage, a.DatePublished 
) SELECT COUNT(*) FROM SearchArticles 
+0

Bien vous ne pouvez pas vous dans Linq simplement définir une variable à OUTPUT et attribuer le compte à cette variable? Mon problème était d'essayer de reconstruire cette requête pour retourner le nombre de lignes. – Patrick

+0

Quelque chose comme ça ne fonctionne que si vous retournez toutes les lignes que vous voulez compter. Cela ressemble à ce que vous voulez est un compte du nombre total de lignes, mais seulement retourner un sous-ensemble d'entre eux pour l'affichage. Droite? Pour obtenir un nombre total, vous devriez être en mesure de changer votre requête pour retourner seulement count (*), et éliminer les clauses group by et order by. – RickNZ

+0

Eh bien, j'ai essayé cela, mais ensuite il renvoie le nombre de mots-clés correspond à la place du nombre de lignes. – Patrick

1

puisque vous récupérez l'ensemble de toute façon avec la partie de data.SearchArticles pourquoi ne pas le faire:

var results = data.SearchArticles(searchString); 
var count = results.Count(); 

results = results.Skip((iPageNum - 1) * iPageSize).Take(iPageSize).ToList(); 

dépend beaucoup de la taille des résultats de retour à si cela est OK.

+0

L'idée générale était d'éviter d'aller chercher l'ensemble des résultats ... Pourquoi retourne-t-il l'ensemble complet des enregistrements? J'essaie de trouver un moyen de voir la requête SQL qui a été produite par cette déclaration. Il retournera beaucoup de lignes si tout doit être tiré. – Patrick

+0

Eh bien, si je devais le faire, alors je voudrais énumérer les résultats plus d'une fois et obtenir un message d'erreur. – Patrick

+0

Si vous voulez éviter de tirer sur l'ensemble entier, je recommanderais une procédure stockée qui retournerait à la fois l'ensemble paginé et le nombre total. Voir cet article: http://www.beansoftware.com/ASP.NET-Tutorials/Paging-Stored-Procedures.aspx – Richard

1

Après avoir lu vos commentaires sur les autres réponses:

SQL Server n'a pas construit dans la pagination. Ainsi, par défaut, une requête va chercher toutes les lignes. Si une requête ne récupère pas toutes les lignes, votre objet ResultSet effectue la recherche pour vous. Si le jeu de résultats n'est pas paginé, il n'est pas nécessaire de parcourir tous les résultats pour vérifier sa propriété Count(), il doit simplement être défini correctement car SQL Server renvoie le nombre de lignes avec les données. Si vous craignez d'aller chercher trop de données en une fois et que votre resultset ne pagaie pas, vous devez d'abord sélectionner le compte, puis créer une requête capable de renvoyer la page de données souhaitée.

À côté: Vous pouvez laisser le distinct de votre choix. Puisque vous regroupez et regroupez, vous avez déjà des résultats distincts.

Questions connexes