[英]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.