解决Entity Framework Core 6.0连接Oracle 12c超时问题
EF Core 6.0 连接 Oracle 12c 超时及TCP连接失败问题排查
我尝试使用Entity Framework Core 6.0连接公司的Oracle 12c服务器,已按照Oracle说明添加Oracle.EntityFrameworkCore包,但通过创建的DbContext连接时出现连接超时错误,错误日志如下:
2022-07-25 15:29:49.014946 ThreadID:1 (ERROR) OracleDatabaseCreator.Exists() : OracleException.Number: -1000 2022-07-25 15:29:49.022577 ThreadID:1 (ERROR) OracleDatabaseCreator.Exists() : Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch) at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch) at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, OracleConnection connRefForCriteria) at Oracle.ManagedDataAccess.Client.OracleConnection.Open() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) at Oracle.EntityFrameworkCore.Storage.Internal.OracleDatabaseCreator.Exists() Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch) at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch) at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, OracleConnection connRefForCriteria) at Oracle.ManagedDataAccess.Client.OracleConnection.Open() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) at Oracle.EntityFrameworkCore.Storage.Internal.OracleDatabaseCreator.Exists() at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists() at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action) Connection request timed out
尝试在连接字符串中添加Connection Timeout=1200参数后,原错误解决但出现新的TCP传输地址连接失败错误,日志如下:
2022-07-25 15:26:25.234429 ThreadID:1 (ERROR) OracleDatabaseCreator.Exists() : OracleException.Number: -6403 2022-07-25 15:26:25.240231 ThreadID:1 (ERROR) OracleDatabaseCreator.Exists() : Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Network Transport: TCP transport address connect failure ---> OracleInternal.Network.NetworkException (0x80004005): Network Transport: TCP transport address connect failure ---> System.Net.Sockets.SocketException (10060): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) at System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state) --- End of stack trace from previous location --- at System.Threading.Tasks.TaskToApm.End(IAsyncResult asyncResult) at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult) at OracleInternal.Network.TcpTransportAdapter.ConnectIterate() at OracleInternal.Network.OracleCommunication.DoConnect(String tnsDescriptor) at OracleInternal.Network.OracleCommunication.Connect(String tnsDescriptor, Boolean doNAHandshake, String IName, ConnectionOption CO) at OracleInternal.ServiceObjects.OracleConnectionImpl.Connect(ConnectionString cs, Boolean bOpenEndUserSession, OracleConnection connRefForCriteria, String instanceName) at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch) at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch) at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, OracleConnection connRefForCriteria) at Oracle.ManagedDataAccess.Client.OracleConnection.Open() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) at Oracle.EntityFrameworkCore.Storage.Internal.OracleDatabaseCreator.Exists() Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Network Transport: TCP transport address connect failure ---> OracleInternal.Network.NetworkException (0x80004005): Network Transport: TCP transport address connect failure ---> System.Net.Sockets.SocketException (10060): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) at System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state) --- End of stack trace from previous location --- at System.Threading.Tasks.TaskToApm.End(IAsyncResult asyncResult) at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult) at OracleInternal.Network.TcpTransportAdapter.ConnectIterate() at OracleInternal.Network.OracleCommunication.DoConnect(String tnsDescriptor) at OracleInternal.Network.OracleCommunication.Connect(String tnsDescriptor, Boolean doNAHandshake, String IName, ConnectionOption CO) at OracleInternal.ServiceObjects.OracleConnectionImpl.Connect(ConnectionString cs, Boolean bOpenEndUserSession, OracleConnection connRefForCriteria, String instanceName) at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch) at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch) at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, OracleConnection connRefForCriteria) at Oracle.ManagedDataAccess.Client.OracleConnection.Open() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) at Oracle.EntityFrameworkCore.Storage.Internal.OracleDatabaseCreator.Exists() at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists() at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action) Network Transport: TCP transport address connect failure
调整C#主文件中的命令超时等参数也无效果,我的OnConfiguring方法如下:
protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseOracle(@"User Id=<Work User ID>;Password=<Password>;Data Source=ANALYTICS;");
使用SQL Developer、DBeaver、Python+cx_Oracle均可正常连接该数据库,推测是.NET Core相关问题。运行环境为Windows 10 21H2 + .NET Core 6,求解决建议。
解决建议
- 匹配Oracle包版本:确保
Oracle.EntityFrameworkCore和Oracle.ManagedDataAccess.Core版本一致,且为6.x系列(对应EF Core 6),避免跨大版本混用。 - 使用完整TNS连接字符串:不要依赖本地tnsnames.ora配置,直接用完整的TNS格式,从SQL Developer中导出正确的配置,示例:
User Id=<Work User ID>;Password=<Password>;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=你的数据库主机IP/域名)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ANALYTICS))); - 禁用IPv6测试:部分环境下.NET Core优先使用IPv6导致连接失败,可在连接字符串中指定IPv4地址,或临时禁用系统IPv6。
- 关闭连接池:在连接字符串中添加
Pooling=false,排除连接池引发的问题,测试成功后再重新启用。 - 检查代理与防火墙:虽然其他工具能连接,但.NET Core网络栈可能有不同的代理设置,尝试关闭本地代理,或在连接字符串中配置代理信息(如果需要)。
- 更新Oracle驱动包:将
Oracle.EntityFrameworkCore和Oracle.ManagedDataAccess.Core更新到最新稳定版,修复已知的.NET Core兼容性问题。 - 验证DNS解析:在命令行执行
ping ANALYTICS和nslookup ANALYTICS,确认数据库别名能正确解析到主机IP,避免DNS解析问题。
内容的提问来源于stack exchange,提问作者jackyboy633
相关产品推荐
相关产品推荐

