【问题标题】:LINQ Datacontext Disposal IssuesLINQ 数据上下文处置问题
【发布时间】:2010-04-14 18:00:44
【问题描述】:

我在下面的 DAL 方法中得到一个Cannot access object: DataContext after it's been disposed。我以为我可以在那里调用 dispose 。 resultIEnumurable,我认为是 IQueryable 导致了这些问题。

我做错了什么?我应该如何处理我的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);
    }

【问题讨论】:

    标签: c# .net linq-to-sql datacontext


    【解决方案1】:

    您在处理完 DataContext 后调用了CopyLinqToDataTable。由于 LINQ 使用延迟执行,所以它只在枚举 result 时,在释放 DataContext 之后执行查询。

    您应该将 DataContext 放在包含 return 语句的 using 块中。
    这将在调用CopyLinqToDataTable 后释放DataContext,避免该问题。

    例如:

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

    using 语句生成一个 finally 块,该块在末尾处理 DataContext using 块的。 (即使抛出异常)

    【讨论】:

    • 只要返回在using我就可以了??谢谢
    • 是的;你会没事的。 (除非您返回 IEnumerable
    • 好吧,出于好奇,IEnumerable 还会在这里失败吗?那怎么退呢?
    • 致电ToArray。因为(再次)延迟执行,如果您返回IEnumerable,查询将不会运行,直到客户端(使用您的返回值)枚举它。通过调用 ToArray 并返回它(可能包含在 ReadOnlyCollection 中),您可以强制立即枚举枚举。
    【解决方案2】:

    在调用Dispose之前,您应该在查询中使用ToList之类的东西

    【讨论】:

    • List 可以绑定到DataGrids 等以及DataTable 吗?如果是这样,我会调查它。就我的返回类型而言,我正在寻找的术语是“具体的”吗?
    【解决方案3】:

    你就不能这样做吗?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多