2010-02-17 7 views
0

J'ai une requête linq, qui est certes assez grande. Je ne peux pas identifier où cela ne va pas parce que cela se produit UNIQUEMENT sur le serveur distant et je n'ai pas l'accès pour le déboguer. Mais c'est fondamentalement comme ça ...Linq retourne aléatoirement des résultats NULL périodiques

Ce code liste tous les 'dossiers' que le membre actuel peut voir. (Les dossiers contiennent des images.)

  if (membership == null || membership.Count() == 0) 
       membership = new string[] { "Guests" }; 

      return DataContext.Folders.Where(f => f.Ring.Keys.Any(k => k.Tag.Id == id)) 
       .Where(i => i.Ring.Keys.Any(t => membership.Contains(t.Tag.Name))).OrderBy(n => n.Date).DefaultIfEmpty(); 

Ce code énumère toutes les « balises », l'utilisateur peut voir (les balises sont contenues dans des anneaux, qui peut être accroché à des dossiers ou des images)

 IQueryable<Models.Tag> tags = null; 
     do 
     { 
      DataContext = new Models.Contexts.DatabaseDataContext(); 

      tags = null; 
      if (membership == null) 
       membership = new string[] { "Guests" }; 

      tags = DataContext.Tags.Where(t => t.Keys.Any(k => k.Ring.Name == category)) 
       .Where(t => t.Keys.Any(k => k.Ring.Keys.Any(c => membership.Contains(c.Tag.Name)))).OrderBy(o => o.Name); 
     } 
     while (tags == null || tags.Count() == 0); 

     return tags; 

I Je l'ai enfermé dans une boucle, à ma grande consternation, pour voir si cela pouvait l'obliger à continuer à appeler jusqu'à ce qu'il ne soit plus nul. Pas de chance, ça revient toujours vide. Encore une fois, ce même code EXACT fonctionne «parfois», et 100% du temps sur TOUT le test en arrière, en interrogeant la base de données SAME. J'ai même essayé différents hébergeurs - tous avec les mêmes échecs une fois qu'il est en ligne. L'adhésion est une chaîne [] qui contient une liste de tous les rôles auxquels le membre appartient.

Folder 
- Id 
- RingId 

Ring 
- Id 
- Name (Nullable) 

Tag 
- Id 
- Name 

Key 
- Id 
- RingId 
- TagId 

Image 
- Id 
- FolderId 
- RingId 

Ceci est la configuration de base de la structure de base de données.

Maintenant, cette requête fonctionne bien sur ma machine locale - dans tous mes tests, etc. Mais quand je le mets en direct, il commence juste à retourner au hasard parfois. Je n'arrive pas à trouver une rime ou une raison pour laquelle, ça marche bien pour quelques requêtes, alors ça arrête juste de retourner les résultats.

L'ensemble de résultats renvoyé est assez volumineux. Je dirais environ 880 articles. Et le nombre de fois où il est accédé par seconde est très, très élevé. Au début, je pensais que c'était juste le stress du nombre de personnes qui y accédaient.

Y at-il des informations que je peux fournir qui pourraient aider à déboguer cela? Il y a quelques autres requêtes similaires à celle-ci - j'ai essayé, essayé et essayé, et je ne peux tout simplement pas reproduire les résultats dans un débogueur. Je reçois toutes sortes d'appels InvalidCastException - mais il n'y a jamais de casting. Tout est retourné en tant que IQueryable - Les vues ne font rien de spécial sauf prendre Guids et transmettre les données d'adhésion du fournisseur d'adhésion ASP.NET - que j'ai vérifié et confirmé que cela fonctionne. (Insertion de données forcées, au lieu de laisser le fournisseur le faire - échoue toujours)

Je vais essayer de fournir toutes les informations nécessaires, mais je suis vraiment frustré - car rien de tout cela n'a de sens pour moi (pourquoi ce serait échouer).

Merci beaucoup pour votre temps. (Tout cela est fait dans .NET 3.5, ASP.NET MVC 1.0, C#) - les objets ont été créés en utilisant LINQ to SQL.

+0

Le contexte de données est jetable, y a-t-il une raison pour laquelle vous ne le mettez pas à la poubelle en enveloppant sa durée de vie dans une instruction using? – Odd

+0

Je ne suis pas familier avec cette pratique. Suggérez-vous de l'emballer de cette manière? Je ne prétends pas être autre chose qu'un débutant. – Ciel

+0

En l'insérant dans une instruction using, vous me donnez une exception System.ObjectDisposedException. Le retour est à l'intérieur de l'instruction using - je ne sais pas vraiment comment extraire les données, si je dois disposer du contexte de données. – Ciel

Répondre

1

Cela ressemble vraiment à un problème de charge. Mettez quelques compteurs de perf sur le serveur Web et observez-le pour l'utilisation.

+0

Comment suggéreriez-vous de le résoudre - si c'est un problème de charge? Je ne cours pas ceci sur un serveur Web bon marché ou faible. Il fonctionne plutôt bien avec d'autres applications à grande échelle. Mais la charge est quelque part entre 10 000 ~ 25 000 coups par heure. – Ciel

+0

Si elle est basée sur la charge, alors votre seule solution va être d'étendre l'application afin que vous ayez assez de serveurs Web pour gérer la charge sans toucher à la limite magique. Au-delà de cela, créez un exemple d'application et contactez le support MS directement pour voir s'ils peuvent corriger le bug. – NotMe

1

Ok Je ne sais pas si cela est votre problème, mais il est trop difficile d'écrire de nouveau dans un commentaire,

Votre contexte de données est disponible, en supposant que vous utilisez LINQ to SQL.Par conséquent, pendant que vous voulez l'utiliser, vous pouvez l'envelopper dans une déclaration en utilisant comme ceci:

do 
    { 
     using (DataContext = new Models.Contexts.DatabaseDataContext()) 
     { 

      tags = null; 
      if (membership == null) 
       membership = new string[] { "Guests" }; 

      tags = DataContext.Tags.Where(t => t.Keys.Any(k => k.Ring.Name == category)) 
       .Where(t => t.Keys.Any(k => k.Ring.Keys.Any(c => membership.Contains(c.Tag.Name)))).OrderBy(o => o.Name); 
     } 
    } 

De cette façon, il disposera de votre connexion après chaque tentative de l'utiliser, sinon il restera en mémoire pendant une certaine période de temps . Puisque cette période de temps dépend du garbage collector, cela pourrait être la raison pour laquelle cela fonctionne à certains moments et pas à d'autres. Essayez-le et laissez-moi savoir si cela a résolu votre problème.

+0

Cela ne fonctionne pas car le contexte de données est éliminé lorsque la vue tente de restituer les données qu'elle a reçues. – Ciel

+0

J'ai aussi essayé de désactiver le chargement paresseux, mais j'ai le même problème. Existe-t-il un moyen d'accéder aux données récupérées après que le DataContext a été éliminé? – Ciel

+0

Contrairement à la plupart des types qui implémentent IDisposable, DataContext n'a pas vraiment besoin d'être éliminé - du moins pas dans la plupart des cas. Voir http://csharpindepth.com/ViewNote.aspx?NoteID=89 –