![](/img/trans.png)
[英]System.ObjectDisposedException: Cannot access a disposed object
[英]System.ObjectDisposedException: 'Cannot access a disposed object.Object name: 'OracleConnection'.'
以下代碼使用Entity Framework 6和Managed Oracle Providers來調用返回多個游標的Oracle存儲過程。
using
語句引發以下異常:
System.ObjectDisposedException: 'Cannot access a disposed object.Object name: 'OracleConnection'.'
如果我刪除了using語句,而是使用以下帖子中的代碼。 我沒有錯誤。
為什么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
,並且在處理數據上下文時將處理連接。
因此:盡管出於執行查詢的目的,您可能被允許從數據上下文中借用連接,但是您不應該嘗試在此處處置它。 最終將在意外的時間關閉/部署連接,從而產生不可預測的結果。
相反:如果您有一個var conn = new OracleConnection(...)
,那么顯然您確實擁有該連接(除非您將其交給可以管理生命周期的對象),並且應該對其進行處置。
只是為了使事情更加復雜...目前,您的MyClass
似乎通過以下方式擁有db-context:
private MyDbContext _dbContext = new MyDbContext();
因此,理想情況下, MyClass
應該是可拋棄的( : IDisposable
),而_dbContext
MyClass
應該級聯以部署_dbContext
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.