gpt4 book ai didi

c# - System.ObjectDisposeException : 'Cannot access a disposed object.Object name: ' OracleConnection'. '

转载 作者:行者123 更新时间:2023-12-03 03:02:42 26 4
gpt4 key购买 nike

以下代码使用 Entity Framework 6 和托管 Oracle 提供程序来调用返回多个游标的 Oracle 存储过程。

using 语句引发以下异常:

 System.ObjectDisposedException: 'Cannot access a disposed object.Object name: 'OracleConnection'.'

如果我删除 using 语句并改为使用以下帖子中的代码。我没有收到任何错误。

Using Entity Framework to Call an Oracle Stored Procedure with Multiple Cursors

为什么using语句会引发异常?有人向我建议 Oracle 托管提供程序存在错误。但是,我的同事正在使用相同的提供程序,并且他们的 using 语句工作正常。

示例代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using Oracle.ManagedDataAccess.Client;
using System.Data.Entity.Infrastructure;

namespace MyCompany
{
public class MyClass
{
private MyDbContext _dbContext = new MyDbContext();

public MyItems GetMyItems(string id)
{
var sqlQuery = "";
var oracleParameters = new List<OracleParameter>();
var oneEntityList = new List<OneEntity>();
var twoEntityList = new List<TwoEntity>();
var threeEntityList = new List<ThreeEntity>();

sqlQuery = @"

BEGIN

MY_PACKAGE.GetMyItems(:id, :p_cursor1, :p_cursor2, :p_cursor3);

END;

";
oracleParameters = new List<OracleParameter>
{
new OracleParameter("p_id", id),
new OracleParameter("p_cursor1", OracleDbType.RefCursor, ParameterDirection.Output),
new OracleParameter("p_cursor2", OracleDbType.RefCursor, ParameterDirection.Output),
new OracleParameter("p_cursor3", OracleDbType.RefCursor, ParameterDirection.Output)
};

using (var connection = _dbContext.Database.Connection)
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = sqlQuery;
command.Parameters.AddRange(oracleParameters.ToArray());
using (var reader = command.ExecuteReader())
{
oneEntityList = ((IObjectContextAdapter)dbContext).ObjectContext
.Translate<OneEntity>(reader)
.ToList();
reader.NextResult();

twoEntityList = ((IObjectContextAdapter)dbContext).ObjectContext
.Translate<TwoEntity>(reader)
.ToList();
reader.NextResult();

threeEntityList = ((IObjectContextAdapter)dbContext).ObjectContext
.Translate<ThreeEntity>(reader)
.ToList();
}

return new MyItems { OneEntity = oneEntityList, TwoEntity = twoEntityList, ThreeEntity = threeEntityList };
}

}
}
}

最佳答案

当您拥有生命周期时,在一次性对象周围使用 using 语句是正确且正确的;然而,在这种情况下:你不!这里的连接属于数据上下文,想必数据上下文本身是IDisposable,当数据上下文被释放时,它就会释放该连接。 p>

所以:虽然您可能被允许从数据上下文中借用连接以执行查询,但您不应该尝试在此处处置它。这最终会在意外的时间关闭/处置连接,从而产生不可预测的结果。


相反:如果您有一个 var conn = new OracleConnection(...),那么显然您拥有该连接(除非你把它交给了管理生命周期的东西),并且你应该处置它。


只是让事情变得更加复杂......目前,您的 MyClass 似乎拥有数据库上下文,通过:

private MyDbContext _dbContext = new MyDbContext();

因此,理想情况下,您的 MyClass 应该是一次性的(: IDisposable),并且处置 MyClass 应该级联处置 _dbContext.

关于c# - System.ObjectDisposeException : 'Cannot access a disposed object.Object name: ' OracleConnection'. ',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53483696/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com