C# 使用ObjectDataSource.Select()方法最终导致异常“操作无法完成,因为DbContext已被释放。”
我不熟悉EF和存储库模式。我理解代码中的问题来自何处,但我不确定什么是正确的解决方案。问题是: 我有一个WebForm,在这里我查询DB以获得一条要显示的记录。我已经实现了业务逻辑层BLL和数据库访问层DAL。在Web表单中,我使用以下ObjectDataSource:C# 使用ObjectDataSource.Select()方法最终导致异常“操作无法完成,因为DbContext已被释放。”,c#,asp.net,entity-framework,repository-pattern,data-access-layer,C#,Asp.net,Entity Framework,Repository Pattern,Data Access Layer,我不熟悉EF和存储库模式。我理解代码中的问题来自何处,但我不确定什么是正确的解决方案。问题是: 我有一个WebForm,在这里我查询DB以获得一条要显示的记录。我已经实现了业务逻辑层BLL和数据库访问层DAL。在Web表单中,我使用以下ObjectDataSource: <asp:ObjectDataSource ID="EmployerObjectDataSource" runat="server" TypeName="IkaManagerWeb.BLL.IkaMgrBL"
<asp:ObjectDataSource ID="EmployerObjectDataSource" runat="server" TypeName="IkaManagerWeb.BLL.IkaMgrBL"
DataObjectTypeName="IkaManagerWeb.BLL.IkaMgrBL"
SelectMethod="GetEmployer"
OnSelecting ="EmployerObjectDataSource_Selecting">
<SelectParameters>
<asp:Parameter Name ="username" Type="String" />
<asp:Parameter Name="version" Type="UInt16" />
</SelectParameters>
</asp:ObjectDataSource>
在上面,我得到一个异常,DBContext已被释放。通过逐步浏览BLL和DAL中的代码,我看到DBContext确实已被释放。事实上
EmployerObjectDataSource.Select();
返回结果,BLL被释放,这反过来导致DAL,因此DBContext被释放
我所想的解决方案是在PopulateFields方法的整个执行过程中保持对BLL的引用。问题是:
使用using block时,这是正确的方法吗?如果是,那么如何获取EmployeerObjectDataSource实例化的BLL对象的引用以执行Select
编辑:通过单步执行代码,我看到了以下事件顺序:
通过调用ObjectDataSource的Select方法,BLL对象被实例化。
BLL正在实例化DAL对象。
DAL对象正在执行底层数据库查询
BLL正在进入状态
在BLL Dispose过程中,调用DAL Dispose-这将删除DBContext
ObjectDataContext的Select方法返回
我一调用emp.Count,emp对象就被枚举,因为DBContext已经被删除,所以我得到了异常。
编辑:根据以下Dmytro的要求,我还提供了BLL的GetEmployer方法:
public IEnumerable<Employer> GetEmployer(string username, short version)
{
DateTime today = DateTime.Today;
IEnumerable<Employer> employers = ikaRepository.GetEmployers(username, today, version);
Debug.Assert(employers.Count() <= 1, "This is a logical Error - Can we have more than one active Employer records per user?");
return employers;
}
请注意,这将正确检索记录
提前谢谢大家,
左撇子看起来像你的台词
IEnumerable<Employer> empl = (IEnumerable<Employer>)EmployerObjectDataSource.Select();
从Select方法返回IQueryable类型。此类型不包含真实数据,也不从数据库获取数据。试着用这样的东西
var empl = ((IEnumerable<Employer>)EmployerObjectDataSource.Select()).ToList();
您是如何定义ObjectDataSoruce的查询的。在您的情况下,我认为您应该删除using block。``@SaeedNeamati ObjectDataSource使用BLL中的函数作为SelectMethod,而BLL反过来调用DAL中的方法。我现在没有使用任何使用块。我将编辑帖子以显示事件的顺序,因为我已经完成了这些步骤。谢谢你,但是,我仍然得到了相同的异常DBContext已被删除仍然是相同的想法-将IEnumerable类型转换为列表类型ikaRepository.GetEmployerUserUserUserName,今天,version.ToList;不过,在访问开发机器之后,我会通过阅读ObjectDataSource.Select方法文档来尝试这一点,我知道GetEmployers应该返回以下类型之一:IEnumerable、DataTable、DataView、DataSet或Object,然后将其转换为IEnumerable。实现IEnumerable,所以Select方法将返回正确的数据类型。这很好地解决了我的问题。查看文档,还有第二种解决问题的方法。有趣的是,使用Selected事件可以在处理BLL对象之前处理返回的值:Selected操作完成后,调用OnSelected方法来引发Selected事件。您可以处理所选事件以检查任何返回值、输出参数和异常,并执行任何后处理。
IEnumerable<Employer> empl = (IEnumerable<Employer>)EmployerObjectDataSource.Select();
var empl = ((IEnumerable<Employer>)EmployerObjectDataSource.Select()).ToList();