使用ODP.NET提供程序的带.NET核心的Oracle DB-如何设置架构

使用ODP.NET提供程序的带.NET核心的Oracle DB-如何设置架构,oracle,.net-core,entity-framework-core,odp.net,Oracle,.net Core,Entity Framework Core,Odp.net,在使用.NET Core中的Oracle数据库时遇到问题 我能够创建到数据库的连接。 我的问题似乎是当我试图执行一条语句时。 我首先使用带有DbContext的EF Core从DB中检索单个实体,在这种情况下,我在以下行中得到异常: var item = _context.CSProf.SingleOrDefault(e => e.Id == id); 异常和跟踪似乎不是很有用 Exception has occurred: CLR/Oracle.ManagedDataAcces

在使用.NET Core中的Oracle数据库时遇到问题

我能够创建到数据库的连接。
我的问题似乎是当我试图执行一条语句时。 我首先使用带有DbContext的EF Core从DB中检索单个实体,在这种情况下,我在以下行中得到异常:

var item = _context.CSProf.SingleOrDefault(e => e.Id == id);
异常和跟踪似乎不是很有用

    Exception has occurred: CLR/Oracle.ManagedDataAccess.Client.OracleException
    An exception of type 'Oracle.ManagedDataAccess.Client.OracleException' occurred in Microsoft.EntityFrameworkCore.dll but was not handled in user code: 'External component has thrown an exception.'
    at OracleInternal.ServiceObjects.OracleConnectionImpl.VerifyExecution(Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, SqlStatementType sqlStatementType, Int32 arrayBindCount, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteReader(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, OracleDataReaderImpl& rdrImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[] scnForExecution, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, Int64& internalInitialLOBFS, OracleException& exceptionForArrayBindDML, OracleConnection connection, OracleLogicalTransaction& oracleLogicalTransaction, IEnumerable`1 adrianParsedStmt, Boolean isDescribeOnly, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
...
我知道无论如何都需要更改模式,因此我也尝试在DbContext构造函数中执行此操作:

var conn = this.Database.GetDbConnection();
conn.Open();
Console.WriteLine("DB Server Version with open conn = " + conn.ServerVersion); //no problem here -version is "12.1.0.2.0"
var command = conn.CreateCommand();
command.CommandText = "ALTER SESSION SET CURRENT_SCHEMA = {SchemaName};";
int res = command.ExecuteNonQuery(); //Error on this line - 'External component has thrown an exception.' at OracleInternal.ServiceObjects.OracleConnectionImpl.VerifyExecution( ...
command.Dispose();
conn.Close();
然后,我还尝试像这样更改模式,使用Oracle.ManagedDataAccess.Client OracleConnection类,而不是通过EFCore的DbContext,得到相同的错误:

var oconn = new OracleConnection({ConnectionString});
oconn.Open();
Console.WriteLine("DB Server Version with open conn = " + oconn.ServerVersion); //no problem here -version is "12.1.0.2.0"
OracleCommand orclCmd = oconn.CreateCommand();
orclCmd.CommandText = "ALTER SESSION SET CURRENT_SCHEMA = {SchemaName};";
int res = orclCmd.ExecuteNonQuery(); // <---- Error on this line - 'External component has thrown an exception.' at OracleInternal.ServiceObjects.OracleConnectionImpl.VerifyExecution( ...
Console.WriteLine("Result of Alter Session Schema = " + res);
orclCmd.Dispose();
oconn.Close();
关于“外部组件引发了异常”的原因或者应该尝试什么,您有什么想法吗

----------------------------------------------

编辑:

在查询实体时,我注意到打印到调试控制台的跟踪中有一些信息比“External component has Trown”(外部组件已抛出)更丰富:

当我将打印到调试控制台的SQL粘贴到SQLDeveloper中时,它返回的结果很好。但是当从我的应用程序执行时,数据库似乎找不到表。听起来我可能不在正确的模式中,但当我执行以下操作时:

SELECT sys_context('userenv', 'current_schema') FROM dual

正如@Sam在注释中所建议的,它返回的模式名称正确,我相信这意味着我已经在正确的模式中了?

因此,最终我意识到我将错误地设置模式。 看起来,虽然数据库连接有正确的模式,但实体框架可能没有意识到正确的模式(或类似的东西)

我在另一篇文章中找到了这个答案,让我明白了这一点: [

如链接答案所示,我只需要将以下行添加到上下文的OnModelCreating方法中,并将相应的模式名称作为参数:

modelBuilder.HasDefaultSchema(string schema);
这并不是针对Oracle的,因为我以前确实必须为MS SQL Server这样做。

(不幸的是,我没有查看另一个项目,也没有更早地发现这个错误。)

尝试执行
SELECT sys\u context('userenv','current\u schema'))从dual
中删除分号,并查看它是否引发任何错误从命令中删除分号string@WernfriedDomscheit:删除分号消除了试图更改架构时的异常,但我从ExecuteOnQuery中获得了-1的返回值,我假设这表明该语句未成功?@Sam:我执行了该查询,结果发现工作正常。返回了一条记录,其中包含我试图更改为的架构的名称。我猜这意味着我已经在使用该架构?是的,看起来您正在登录到您试图更改的同一架构,正如@WernfriedDomscheit建议的,您不应该使用“;”和花括号是什么?
SELECT sys_context('userenv', 'current_schema') FROM dual
modelBuilder.HasDefaultSchema(string schema);