Проблемы утилизации LINQ Datacontext - PullRequest
2 голосов
/ 14 апреля 2010

Я получаю Cannot access object: DataContext after it's been disposed в приведенном ниже методе DAL. Я думал, что я буду в порядке, позвонив распоряжаться там. result - это IEnumurable, и я подумал, что именно 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);
    }

Ответы [ 3 ]

7 голосов
/ 14 апреля 2010

Вы звоните CopyLinqToDataTable после утилизации DataContext. Поскольку LINQ использует отложенное выполнение, он выполняет запрос только при перечислении result, после удаления DataContext.

Вы должны поместить свой DataContext в блок using, содержащий оператор return.
Это позволит избавиться от DataContext после вызова CopyLinqToDataTable, чтобы избежать проблемы.

Например:

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

Оператор using создает блок finally, который удаляет DataContext в конце блока using. (Даже если выдается исключение)

4 голосов
/ 14 апреля 2010

Вы должны использовать что-то вроде ToList в запросах перед вызовом Dispose

1 голос
/ 14 апреля 2010

Разве вы не можете просто сделать это вместо этого?

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