Oracle БД с. NET Ядро с использованием ODP. Net Провайдер - Как настроить схему - PullRequest
1 голос
/ 30 марта 2020

Возникли проблемы при работе с базой данных Oracle в. NET Core.

Я могу создать соединение с базой данных.
Кажется, у меня проблема при попытке выполнить оператор. Сначала я использовал EF Core с DbContext для извлечения отдельного объекта из БД, и в этом случае я получаю исключение в следующей строке:

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 вместо прохождения через DbContext EFCore, получая ту же ошибку:

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();

Вот мой env:

Windows Server 2016 
Developing / Debugging in VS Code 
.NETCoreApp,Version=v3.1 
Microsoft.EntityFrameworkCore/2.1.11 Microsoft.EntityFrameworkCore.Relational/2.1.11 Oracle.EntityFrameworkCore/2.19.60 
Oracle.ManagedDataAccess.Core/2.19.60

Любые идеи о том, что может быть причиной этого "Внешний компонент выдал исключение" или что попробовать?

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

Редактировать:

По запросу для сущности я заметил, что что-то есть чуть более информативным в трассировке, выведенной на консоль отладки, кроме просто «Внешний компонент сгенерирован»:

Microsoft.EntityFrameworkCore.Database.Command: Error: 2020-03-30 10:18:31.153037 ThreadID:4   (ERROR)   OracleRelationalCommand.Execute() :  Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-00942: table or view does not exist

Когда я вставляю SQL, напечатанный на консоль отладки, в SQL Developer, он возвращает результаты просто отлично. Но при выполнении из моего приложения база данных не может найти таблицу. Звучит так, как будто я не в правильной Схеме, но когда я выполняю следующее:

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

, как предложено @Sam в комментариях, он возвращается с правильным именем Схемы, которое, я считаю, означает, что я ' м уже в правильной схеме?

1 Ответ

0 голосов
/ 30 марта 2020

Итак, в конце концов я понял, что собираюсь неправильно настроить схему. Кажется, что, хотя подключение к базе данных имело правильную схему, Entity Framework, возможно, не знал о правильной схеме (или что-то в этом роде).

Я нашел этот ответ в другом посте, в котором я понял: [{ ссылка }] [1]

Как показано в связанном ответе, мне просто нужно было добавить следующая строка для метода OnModelCreating для моего контекста с соответствующим именем схемы в качестве аргумента:

modelBuilder.HasDefaultSchema(string schema);

Это не специфицируется c до Oracle, так как на самом деле мне приходилось делать это раньше для MS SQL Server.
(К сожалению, я не смотрел на этот другой проект и скорее уловил эту ошибку.)

...