简体   繁体   English

LINQ Datacontext处理问题

[英]LINQ Datacontext Disposal Issues

I am getting a Cannot access object: DataContext after it's been disposed in the below DAL method. 我得到一个Cannot access object: DataContext after it's been disposed在下面的DAL方法之后。 I thought that I would be okay calling dispose there. 我以为我可以在那里打电话处理。 result is an IEnumurable and I thought it was IQueryable that caused these kinds of problems. result是一个IEnumurable ,我认为它是IQueryable导致这些问题。

What am I doing wrong? 我究竟做错了什么? How SHOULD I be disposing of my DataContext . 应该如何处理我的DataContext Is there something better to be returning then a DataTable ? 有没有更好的东西返回DataTable This is a Desktop app that points at SQL 2005. 这是一个指向SQL 2005的桌面应用程序。

Example method that causes this error --> 导致此错误的示例方法 - >


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

partial class where I create the DataContext --> 我创建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);
    }

You're calling CopyLinqToDataTable after disposing the DataContext. 在处理DataContext之后,您正在调用CopyLinqToDataTable Since LINQ uses deferred execution, it only executes the query when result is enumerated, after the DataContext is disposed. 由于LINQ使用延迟执行,它仅当执行该查询result被列举在DataContext设置之后。

You should put your DataContext in a using block that contains the return statement. 您应该将DataContext放在包含return语句的using块中。
This will dispose the DataContext after calling CopyLinqToDataTable , avoiding the problem. 这将在调用CopyLinqToDataTable之后CopyLinqToDataTable DataContext,从而避免此问题。

For example: 例如:

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

The using statement generates a finally block that disposes the DataContext at the end of the using block. using语句生成一个finally块,在using块的末尾处理DataContext。 (Even if an exception is thrown) (即使抛出异常)

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

Can't you just do this instead? 你不能这样做吗?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM