LINQ 数据上下文处置问题

发布于 2024-08-29 06:09:26 字数 3377 浏览 5 评论 0原文

在下面的 DAL 方法中,我收到 Cannot access object: DataContext after it's was dispose 。我想我可以在那里打电话处理。 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);
    }

I am getting a Cannot access object: DataContext after it's been disposed in the below DAL method. 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.

What am I doing wrong? How SHOULD I be disposing of my DataContext. Is there something better to be returning then a DataTable? This is a Desktop app that points at 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 -->


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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空‖城人不在 2024-09-05 06:09:26

您在处置 DataContext 后调用 CopyLinqToDataTable。由于 LINQ 使用延迟执行,因此它仅在 DataContext 被释放后枚举 result 时才执行查询。

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

例如:

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

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

You're calling CopyLinqToDataTable after disposing the DataContext. Since LINQ uses deferred execution, it only executes the query when result is enumerated, after the DataContext is disposed.

You should put your DataContext in a using block that contains the return statement.
This will dispose the DataContext after calling CopyLinqToDataTable, avoiding the problem.

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. (Even if an exception is thrown)

扭转时空 2024-09-05 06:09:26

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

You should use something like ToList in queries before calling Dispose

晚风撩人 2024-09-05 06:09:26

你就不能这样做吗?

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

Can't you just do this instead?

...
DataTable dt = result.CopyLinqToDataTable(); 
DB.Dispose(); 
return dt;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文