LINQ 数据上下文处置问题
在下面的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您在处置 DataContext 后调用
CopyLinqToDataTable
。由于 LINQ 使用延迟执行,因此它仅在 DataContext 被释放后枚举result
时才执行查询。您应该将 DataContext 放入包含
return
语句的using
块中。这将在调用
CopyLinqToDataTable
后处置DataContext,从而避免该问题。例如:
using
语句生成一个finally
块,该块在最后处理 DataContextusing
块的。 (即使抛出异常)You're calling
CopyLinqToDataTable
after disposing the DataContext. Since LINQ uses deferred execution, it only executes the query whenresult
is enumerated, after the DataContext is disposed.You should put your DataContext in a
using
block that contains thereturn
statement.This will dispose the DataContext after calling
CopyLinqToDataTable
, avoiding the problem.For example:
The
using
statement generates afinally
block that disposes the DataContext at the endof the
using
block. (Even if an exception is thrown)在调用
Dispose
之前,您应该在查询中使用类似ToList
的内容You should use something like
ToList
in queries before callingDispose
你就不能这样做吗?
Can't you just do this instead?