升级至Oracle 19版本后ObjectContext.Translate无法正常工作的问题求助
问题描述
项目基于.NET Framework 4.6.2开发,升级Oracle数据库至19版本后,调用存储过程结果转实体类的方法时出现报错。
报错详情
- 报错代码行:
res = ((IObjectContextAdapter)db).ObjectContext.Translate<T>(reader).ToList<T>(); - 报错信息:
从数据库获取提供程序信息时发生错误。这可能是由于Entity Framework使用了不正确的连接字符串。请检查内部异常详情并确保连接字符串正确。
涉及方法代码
public static List<T> GetListBySP<T>(string pSPName, params object[] pParamArray) { List<T> res = null; //string connStr = ConfigurationManager.ConnectionStrings[sConnStr].ConnectionString; string connStr = DbFactory.ConnStr; using (OracleConnection conn = new OracleConnection(connStr)) { using (OracleCommand cmd = new OracleCommand()) { cmd.Connection = conn; cmd.CommandText = pSPName; cmd.CommandType = CommandType.StoredProcedure; FillParameters(cmd.Parameters, pParamArray); cmd.Parameters.Add("pCursor", OracleDbType.RefCursor).Direction = ParameterDirection.Output; using (var db = DbFactory.CreateRo()) { try { cmd.Connection.Open(); var reader = cmd.ExecuteReader(); res = ((IObjectContextAdapter)db).ObjectContext.Translate<T>(reader).ToList<T>(); } catch (Exception ex) { throw ex; } finally { cmd.Connection.Close(); } } } } return res; }
解决方案建议
1. 匹配ODP.NET版本
Oracle 19c需要对应版本的Oracle Data Provider for .NET (ODP.NET)支持,旧版本组件大概率不兼容19c。确认项目引用的ODP.NET版本为12.2及以上,优先选择与Oracle 19c匹配的最新稳定版。
2. 校验连接字符串
确保DbFactory.ConnStr返回的连接字符串符合Oracle 19c要求:
- 必须使用ODP.NET格式,弃用已淘汰的System.Data.OracleClient格式
- 示例正确格式:
Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=你的主机地址)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=你的服务名)));User Id=用户名;Password=密码; - 若使用EDMX模型,检查连接字符串中
Metadata参数是否指向正确的模型文件路径。
3. 修复连接实例不一致问题
当前代码存在核心问题:手动创建的OracleConnection和DbFactory.CreateRo()返回的上下文使用独立连接实例,而Translate方法要求上下文连接与DataReader的连接必须一致,否则会触发提供程序信息错误。
修改后的代码示例:
public static List<T> GetListBySP<T>(string pSPName, params object[] pParamArray) { List<T> res = null; using (var db = DbFactory.CreateRo()) { var conn = db.Database.Connection as OracleConnection; try { conn.Open(); using (OracleCommand cmd = new OracleCommand(pSPName, conn)) { cmd.CommandType = CommandType.StoredProcedure; FillParameters(cmd.Parameters, pParamArray); cmd.Parameters.Add("pCursor", OracleDbType.RefCursor).Direction = ParameterDirection.Output; var reader = cmd.ExecuteReader(); res = ((IObjectContextAdapter)db).ObjectContext.Translate<T>(reader).ToList<T>(); } } catch (Exception ex) { throw ex; } finally { conn.Close(); } } return res; }
4. 查看内部异常
捕获异常时不要直接抛出原异常,优先查看ex.InnerException的具体信息,这能精准定位问题根源,比如权限不足、服务名错误、组件版本不兼容等。
内容的提问来源于stack exchange,提问作者Tzof
相关产品推荐
相关产品推荐

