2014-06-10 3 views
0

Nous avons une application Silverlight qui appelle un service Web pour récupérer des lignes de base de données à partir de SQL Server. Ceux-ci sont ensuite affichés sur l'écran dans un contrôle paginé. Cependant, la table entière est nécessaire et elle se compose de plusieurs milliers de lignes. Sur le système client, si nous demandons plus de 1500 lignes environ, nous obtenons HttpRequestTimedOutWithoutDetail. Sur notre système de développement, nous avons besoin de 500 000 lignes avant que cela n'arrive. De toute évidence, ce que nous devrions faire est de paginer les résultats et de les renvoyer petit à petit à Silverlight. Mais je ne sais pas comment faire ça. Quelqu'un peut-il conseiller, ou me pointer vers des pages Web qui expliquent clairement les principes et les méthodes (je suis un peu simple!)Résultats du service Web de pagination Silverlight

Voici le code dans le service Web:

public IQueryable<Referral> GetReferrals() 
    { 
     /* 
     * In the customer's environments it seems that any more than around 1500 referrals will break the system: they will fail to load. 
     * In the dev environment is takes around 500,000 so it seems to be timeout related. 
     * 
     * The code below was an attempt to restrict the number, only returning referrals above a certain size and within a certain age. 
     * It seems the customer is more interested in the smaller referrals though since they are more likely to be added to existing 
     * substations so if this method is re-instated, we should be using '<' instead of '>' 
     * 
     int mdToBeMet = int.Parse(ConfigurationManager.AppSettings["ReferralMDToBeMet"]); 
     DateTime minusNYears = DateTime.Today.AddYears(int.Parse(ConfigurationManager.AppSettings["ReferralTargetDate"]) * -1); 
     int maxReferralsCount = int.Parse(ConfigurationManager.AppSettings["ReferralMaxRecordCount"]); 
     if (mdToBeMet != 0 && maxReferralsCount != 0) 
     { 
      return this.ObjectContext.Referrals.Where(x => x.MD_to_be_Met > mdToBeMet && x.Target_Date > minusNYears).OrderByDescending(y => y.Target_Date).Take(maxReferralsCount); 
     } 
     */ 

     /* 
     * This is the 2nd attempt: the customer is mainly interested in referrals that have an allocated substation 
     */ 
     bool allocatedReferralsOnly = bool.Parse(ConfigurationManager.AppSettings["ReferralAllocatedOnly"]); 
     int maxReferralsCount = int.Parse(ConfigurationManager.AppSettings["ReferralMaxRecordCount"]); 

     if (allocatedReferralsOnly) 
     { 
      var referrals = this.ObjectContext.Referrals.Where(x => x.Sub_no != "").OrderByDescending(y => y.Target_Date).Take(maxReferralsCount); 
      return referrals; 
     } 
     else 
     { 

      /* 
      * Ideally, we should just page the referrals here and return to retrieving all of them, bit by bit. 
      */ 
      var referrals = this.ObjectContext.Referrals; 
      return referrals; 
     } 
    } 

Un grand merci pour Aucune suggestion.

+0

En supposant que vous utilisez LINQ pour interroger votre base de données, regardez 'skip' et' take'. Vous pouvez alors faire quelque chose comme 'var résultat = context.Customers.Skip (pageSize * pageNumber) .Take (pageSize)' – Mashton

+0

J'ai ajouté le code à la question. Notre solution consiste à obtenir uniquement les lignes les plus «importantes» et à restreindre à 1500 (en utilisant «Take») s'il y en a plus. Suggérez-vous que j'utilise Sauter pour faire une boucle, en prenant 1500 lignes et en les ajoutant au résultat jusqu'à ce que j'en ai tout le lot (nombre de lignes retournées user41013

+0

Si c'est LINQ2SQL ou quelque chose de similaire, alors utiliser 'Skip' sera traduit dans le sql ... donc il ne ramènera pas les enregistrements X juste pour les ignorer: le sql généré fera le saut. – Mashton

Répondre

0

Un exemple pour développer le commentaire que j'ai donné ...

/// <summary> 
/// Returns a page of Referrels 
/// pageNumber is 0-index based 
/// </summary> 
public IQueryable<Referrel> GetReferrals(int pageNumber) 
{ 
    var pageSize = 100; 
    return ObjectContext.Referrals.Skip(pageNumber*pageSize).Take(pageSize); 
} 

vous pourriez aussi bien passer dans le pageSize aussi si vous voulez, ou le définir comme une constante quelque part en dehors de cette méthode.

Questions connexes