2010-04-14 36 views
2

我在下面的DAL方法中得到了Cannot access object: DataContext after it's been disposed。我認爲我可以打電話在那裏處理。 resultIEnumurable,我認爲這是導致這些問題的IQueryableLINQ Datacontext處理問題

我在做什麼錯?如何SHOULD我正在處置我的DataContext。有沒有更好的回報,然後DataTable?這是一個桌面應用指向在SQL 2005

導致此錯誤

實施例方法 - >


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(); 
    } 

部分類哪裏創建在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); 
    } 

回答

7

您在處理DataContext之後調用CopyLinqToDataTable。由於LINQ使用延遲執行,因此在處理DataContext後,它只在枚舉result時執行查詢。

您應該將您的DataContext置於包含return語句的using塊中。
這將在調用CopyLinqToDataTable後處理DataContext,避免出現問題。

例如:

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

using語句生成finally塊部署在DataContext在結束時using塊的 。 (即使有異常拋出)

+0

只要返回在'使用'我會沒事的?謝謝 – 2010-04-14 18:03:19

+1

是的;你會沒事的。 (除非你返回'IEnumerable') – SLaks 2010-04-14 18:04:13

+0

好吧,出於好奇,'IEnumerable'仍然會在這裏失敗?那麼你如何歸還? – 2010-04-14 18:09:54

4

你應該使用類似的查詢ToList調用Dispose

+0

'List'可以綁定到'DataGrids'之類以及'DataTable'嗎?如果是的話,我會研究它。就我的返回類型而言,我正在尋找「具體」這個術語嗎? – 2010-04-14 18:04:22

1

你就不能做到這一點,而不是之前?

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