2011-08-28 5 views
2

Prenant mon premier coup que l'utilisation de la méthode OnSelecting de LinqDataSource pour que je puisse spécifier une requête plus complexe, j'ai écrit ceci:Dois-je faire confiance à LinqDataSource pour nettoyer correctement?

protected void CategoriesDataSource_OnSelecting(object sender, LinqDataSourceSelectEventArgs e) 
    { 
     using (DataLayerDataContext db = new DataLayerDataContext()) 
     { 
      e.Result = (from feed in db.Feeds 
         where feed.FeedName.StartsWith("Google") 
         select feed.MainCategory).Distinct(); 
     } 
    } 

Le problème, bien sûr, est que la clause en utilisant disposera le DataLayerDataContext. La «solution» est de l'écrire sans elle, mais j'ai peur que le contexte ne soit pas éliminé en temps opportun, qu'il laisse un tas de connexions ouvertes jusqu'à ce que la collecte des données soit effectuée, et ainsi de suite.

Je ne suis pas un expert dans ce domaine, donc des commentaires sur si c'est un vrai problème, ou suis-je inquiet pour rien?

Répondre

3

Ah, une autre personne brûlée par les effets secondaires malheureux de chargement différé ...

protected void CategoriesDataSource_OnSelecting(object sender, LinqDataSourceSelectEventArgs e) 
{ 
    using (DataLayerDataContext db = new DataLayerDataContext()) 
    { 
     e.Result = (from feed in db.Feeds 
        where feed.FeedName.StartsWith("Google") 
        select feed.MainCategory).Distinct().ToList(); 
     //            ^^^^^^^^^ 
    } 
} 

Cela forcera le DataLayerDataContext à exécuter immédiatement la requête et créer une en mémoire la liste qui est ne dépend pas du contexte ou connexion. De cette façon, vous obtenez vos résultats immédiatement et vous pouvez disposer du contexte quand vous le souhaitez.

Le seul problème (selon le commentaire de Steven) est les propriétés de navigation paresseuses; même si vous forcez la requête à évaluer, si vous essayez d'interroger des propriétés qui sont des références à d'autres objets LINQ (ou des listes d'objets LINQ), ils ne pourront pas charger sauf si vous spécifiez quelles propriétés sont immédiatement requises dans le DataLoadOptions du DataContext. Voir le exemple ci-dessous:

protected void CategoriesDataSource_OnSelecting(object sender, LinqDataSourceSelectEventArgs e) 
{ 
    using (DataLayerDataContext db = new DataLayerDataContext()) 
    { 
     DataLoadOptions loadOptions = new DataLoadOptions(); 
     loadOptions.LoadWith<Category>(c => c.SomeReference); 
     loadOptions.LoadWith<Category>(c => c.SomeOtherReferences); 

     db.LoadOptions = loadOptions; 

     e.Result = (from feed in db.Feeds 
        where feed.FeedName.StartsWith("Google") 
        select feed.MainCategory).Distinct().ToList(); 
    } 
} 

Une fois que vous spécifiez manuellement ces associations, LINQ to SQL les charger avec impatience en mémoire lorsque la requête exécute, au lieu de les laisser à la charge différée (ce qui entraînera une exception lorsque la les propriétés sont utilisées après que le DataContext a été éliminé.)

+0

Le problème avec ceci est cependant que cela ne fonctionne toujours pas avec les propriétés de chargement paresseux. Les y accéder après que le contexte soit éliminé lancera une exception 'ObjectDisposedException'. – Steven

+1

Exactement. J'ai modifié ma réponse. –

Questions connexes