2010-04-14 3 views
2

Je reçois un Cannot access object: DataContext after it's been disposed dans la méthode DAL ci-dessous. Je pensais que je serais d'accord appelant disposer là. result est un IEnumurable et je pensais que c'était IQueryable qui a causé ce genre de problèmes.LINQ Datacontext Problèmes de mise au rebut

Qu'est-ce que je fais mal? Comment DEVRAIT Je me débarrasse de mon DataContext. Y at-il quelque chose de mieux à retourner alors un DataTable? Ceci est une application de bureau qui pointe vers SQL 2005.

méthode

Exemple qui provoque cette erreur ->


public static DataTable GetEnrolledMembers(Guid workerID) 
    { 
     var DB = CmoDataContext.Create(); 

     var AllEnrollees = from enrollment in DB.tblCMOEnrollments 
          where enrollment.CMOSocialWorkerID == workerID || enrollment.CMONurseID == workerID 
          join supportWorker in DB.tblSupportWorkers on enrollment.EconomicSupportWorkerID 
           equals supportWorker.SupportWorkerID into workerGroup 
          from worker in workerGroup.DefaultIfEmpty() 
          select 
           new 
           { 
            enrollment.ClientID, 
            enrollment.CMONurseID, 
            enrollment.CMOSocialWorkerID, 
            enrollment.EnrollmentDate, 
            enrollment.DisenrollmentDate, 
            ESFirstName = worker.FirstName, 
            ESLastName = worker.LastName, 
            ESPhone = worker.Phone 
           }; 

     var result = from enrollee in AllEnrollees.AsEnumerable() 
        where (enrollee.DisenrollmentDate == null || enrollee.DisenrollmentDate > DateTime.Now) 
        //let memberName = BLLConnect.MemberName(enrollee.ClientID) 
        let lastName = BLLConnect.MemberLastName(enrollee.ClientID) 
        let firstName = BLLConnect.MemberFirstName(enrollee.ClientID) 
        orderby enrollee.DisenrollmentDate ascending, lastName ascending 
        select 
         new 
         { 
          enrollee.ClientID, 
          //MemberName = memberName, 
          LastName = lastName, 
          FirstName = firstName, 
          NurseName = BLLAspnetdb.NurseName(enrollee.CMONurseID), 
          SocialWorkerName = BLLAspnetdb.SocialWorkerName(enrollee.CMOSocialWorkerID), 
          enrollee.EnrollmentDate, 
          enrollee.DisenrollmentDate, 
          ESWorkerName = enrollee.ESFirstName + " " + enrollee.ESLastName, 
          enrollee.ESPhone 
         }; 
     DB.Dispose(); 

     return result.CopyLinqToDataTable(); 
    } 

classe partielle où je crée le DataContext ->


partial class CmoDataContext 
{ 
    public static bool IsDisconnectedUser 
    { 
     get 
     { 
      return Settings.Default.IsDisconnectedUser; 
     } 
    } 

    public static CmoDataContext Create() 
    { 
     var cs = IsDisconnectedUser ? Settings.Default.CMOConnectionString : Settings.Default.Central_CMOConnectionString; 
     return  new CmoDataContext(cs); 
    } 

Répondre

7

Vous appelez CopyLinqToDataTable après avoir éliminé le DataContext. Étant donné que LINQ utilise l'exécution différée, il n'exécute la requête que lorsque result est énuméré, après la disposition de DataContext.

Vous devez placer votre DataContext dans un bloc using qui contient l'instruction return.
Cela disposera le DataContext après avoir appelé le CopyLinqToDataTable, évitant ainsi le problème.

Par exemple:

using(var DB = CmoDataContext.Create()) { 
    //Execute queries 
    return result.CopyLinqToDataTable(); 
} 

La déclaration using génère un bloc finally qui dispose DataContext à la fin du bloc using. (Même si une exception est levée)

+0

tant que le retour est dans le 'using' je vais bien? Merci –

+1

Oui; ça ira. (Sauf si vous renvoyez un 'IEnumerable') – SLaks

+0

Bon, par curiosité,' IEnumerable' échouera toujours ici? Comment le retournez-vous alors? –

4

Vous devez utiliser quelque chose comme ToList dans les requêtes avant d'appeler Dispose

+0

Est-ce que 'List' peut être lié à' DataGrids' et similaires ainsi qu'à 'DataTable'? Si oui, je vais y regarder. Est-ce que le terme que je cherche est "concret" dans la mesure où mon type de retour? –

1

Tu ne peux pas faire juste ce lieu?

... 
DataTable dt = result.CopyLinqToDataTable(); 
DB.Dispose(); 
return dt; 
Questions connexes