2009-01-19 3 views
0

Je suis dans le besoin de transmettre des résultats de la base de données. Au lieu de passer un ensemble de données entier, ou une requête sql construite, j'ai essayé de passer un objet configuré LinqDataSource.Passage de LinqDataSource via la session: 'DataContext accessible après Dispose.'

Sur la page source, je configure les propriétés de l'objet LinqDataSource et WhereParameters en utilisant les valeurs définies par l'utilisateur sur les commandes affichées sur la page (boîte de recherche, zone de liste déroulante, etc.). Je passe l'objet autour pour éviter la reconfiguration LinqDataSource sur la page du récepteur.

Mais, même si cela a fonctionné très bien sur mon système de développement, après le déploiement sur un serveur dédié j'ai eu une erreur en disant ce qui suit:

Impossible d'accéder à un objet disposé.

Nom de l'objet: 'DataContext accessible après Dispose.'.

Sur les deux pages, la source et le récepteur, les objets LinqDataSource sont déclarés comme:

<asp:LinqDataSource ID="myLinqDS" runat="server" 
    ContextTypeName="MyProject.MyDBNamedpace.MyDataContext" 
    TableName="TheTable" 
    OrderBy="field1, field2" 
</asp:LinqDataSource> 

Pour passer l'objet DataSource autour de moi ceci:

SetLinqDataSourceWhereAndHisParameters(); //just set Where and WhereParameters 
Guid guid = Guid.NewGuid(); 
Session[guid.ToString()] = myLinqDS; 
ScriptManager.RegisterStartupScript(this.Page, 
    typeof(Page), 
    "Redirect", 
    String.Format(@"window.open(""{0}"");", 
     this.ResolveClientUrl("~/PageToDisplayTheData.aspx?guid=" + 
     System.Web.HttpUtility.UrlEncode(guid.ToString()) 
    ), 
true); 

Et pour récupérer , sur le codebehind de PageToDisplayTheData.aspx:

myLinqDS = 
    (LinqDataSource)Session[System.Web.HttpUtility.UrlDecode(Request.QueryString[guid])]; 
aDataList.DataSource = myLinqDS; 
aDataList.DataBind(); 

Répondre

2

Vous devriez pas être stocker les DataContext en session (ou ailleurs) pour les raisons suivantes:

  • Le DataContext est pas thread sûr
  • Le DataContext est conçu comme une unité Of- outil de travail

Si vous interrogez une collection dans le DataContext il est mis en mémoire cache interne, de sorte que lorsque vous effectuez une nouvelle requête, il vous ne faites pas un aller-retour à la base de données. Mais cela peut entraîner une stagnation des données car les valeurs ne reflètent pas l'état réel de la base de données sous-jacente.

0

Quel est votre objectif? Si vous voulez empêcher l'application de revenir à la base de données, vous devrez quand même mettre en cache l'intégralité du jeu de données. Si vous essayez simplement de ne pas avoir à recréer la requête, pourquoi ne pas ajouter la requête à votre contexte de données comme méthode et la référencer à partir de là partout.

public partial class MyDataContext 
{ 
    public Table<MyTable> OrderedTable() 
    { 
     return this.TheTable.OrderBy(t => t.field1) 
          .ThenBy(t => t.field2); 
    } 
} 
+0

Le jeu de résultats est filtré à l'aide des données fournies par l'utilisateur: recherche, zones de liste déroulante, boutons radio, etc. Dans l'exemple ci-dessus, j'ai encapsulé cette logique sur SetLinqDataSourceWhereAndHisParameters(). – Seiti

+0

Et je sais que passer LinqDataSource va à nouveau frapper la base de données, à cause du comportement de linq. Je voulais juste éviter de passer moins d'infos et devoir répéter des opérations (DRY?) – Seiti

0

les propriétés viennent d'être copiés d'un objet à l'autre et cela a fonctionné:

LinqDataSource received= 
(LinqDataSource)Session[System.Web.HttpUtility.UrlDecode(Request.QueryString[guid])]; 

myLinqDS.Where = received.Where; 
foreach (Parameter p in received.WhereParameters) 
    myLinqDS.WhereParameters.Add(p); 

Mais je sais ne pas encore pourquoi il a travaillé sur le serveur Web interne VS2008 mais pas sur le serveur principal, en cours d'exécution IIS.

Questions connexes