Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用ObjectDataSource.Select()方法最终导致异常“操作无法完成,因为DbContext已被释放。”_C#_Asp.net_Entity Framework_Repository Pattern_Data Access Layer - Fatal编程技术网

C# 使用ObjectDataSource.Select()方法最终导致异常“操作无法完成,因为DbContext已被释放。”

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"

我不熟悉EF和存储库模式。我理解代码中的问题来自何处,但我不确定什么是正确的解决方案。问题是:

我有一个WebForm,在这里我查询DB以获得一条要显示的记录。我已经实现了业务逻辑层BLL和数据库访问层DAL。在Web表单中,我使用以下ObjectDataSource:

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