#c# #.net-core #entity-framework-core #ado.net #oracle18c
#c# #.net-ядро #сущность-фреймворк-ядро #ado.net #oracle18c
Вопрос:
Мне трудно работать с самым недружелюбным по совместимости движком базы данных, когда-либо известным как Oracle.
У меня есть этот пользовательский тип:
CREATE OR REPLACE TYPE INTEGERS_ARRAY AS TABLE OF INTEGER;
И эта простая хранимая процедура:
CREATE OR REPLACE PROCEDURE TEST_PROCEDURE_MAHMOUD(
holy_array IN INTEGERS_ARRAY,
some_kind_of_number1 IN NUMBER,
some_kind_of_number2 IN NUMBER,
query_result OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN query_result FOR
SELECT CODE,AIRWAYBILL_DATE,REFERENCE1,REFERENCE2 FROM SHIPMENTS
ORDER BY AIRWAYBILL_DATE DESC
FETCH NEXT 10 ROWS ONLY;
end;
Эта хранимая процедура является упрощенной версией другой очень сложной процедуры, которая также не работает. У меня одно и то же исключение для обоих:
Oracle.Управляемый доступ к данным.Клиент.Исключение
OracleException ORA-06550: строка 1, столбец 7:
PLS-00306: неправильное число или типы аргументов при вызове ‘TEST_PROCEDURE_MAHMOUD’
ORA-06550: строка 1, столбец 7: PL / SQL: оператор игнорируется
Это то, что я пытался сделать на C#:
var result = new List<string>();
using(var con = new OracleConnection(connectionString))
{
using(var command = con.CreateCommand())
{
con.Open();
command.CommandText = "TEST_PROCEDURE_MAHMOUD";
command.CommandType = System.Data.CommandType.StoredProcedure;
// Parameters
var array = new OracleParameter("holy_array", OracleDbType.Int64, ParameterDirection.Input);
array.UdtTypeName = "MY_SCHEMA.INTEGERS_ARRAY";
array.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
array.Size = 100;
array.Value = new int[] { 100, 101 };
var number1 = new OracleParameter("some_kind_of_number1", OracleDbType.Int64, 1, ParameterDirection.Input);
var number2 = new OracleParameter("some_kind_of_number2", OracleDbType.Int64, 1, ParameterDirection.Input);
var cursor = new OracleParameter("query_result", OracleDbType.RefCursor, ParameterDirection.Output);
command.Parameters.AddRange(new[] { array, number1, number2, cursor });
var reader = command.ExecuteReader();
while (reader.Read())
{
var awb = reader.GetString(0);
result.Add(awb);
}
}
}
return resu<
Разве Oracle не должен понимать очень простой (таблица целых чисел) тип и принимать массив целых чисел для этого типа? Как я могу решить эту проблему? Я просмотрел документацию на официальном сайте, я прочитал примеры кода на GitHub, я много искал и не смог найти ни одного рабочего примера, только обходные решения, такие как создание временной таблицы, которую я не хочу делать.
Заранее спасибо.
РЕДАКТИРОВАТЬ: основной тег Entity Framework связан с тем, что сначала я пытался сделать это с EF Core, но это не сработало, я переключился на ADO.NET , думая, что это может быть проблемой EF Core. Но оказывается, что ядро EF слишком хорошо, чтобы так меня подвести.
Ответ №1:
К сожалению, ядро Entity Framework по-прежнему не полностью поддерживает базы данных Oracle, одним из ограничений являются пользовательские типы:
Ограничения Выделенная команда успешно реализовала большинство функций, максимально поддерживающих функциональность Entity Framework для сервера Oracle, но есть некоторые ограничения, которые невозможно преодолеть.
Oracle не имеет своих эквивалентов для конструкций ВНЕШНЕГО ПРИМЕНЕНИЯ и ПЕРЕКРЕСТНОГО ПРИМЕНЕНИЯ SQL Server. Пользовательские типы, включая объекты Oracle, типы массивов и вложенные таблицы, не поддерживаются.
Комментарии:
1. Абсолютно неясно, к какой версии это относится. 2nd? Сейчас я использую EFCore 5 и до сих пор не могу понять, актуально ли это (данное сообщение относится к 2018 году).
2. Это всегда актуально, к сожалению, Oracle и .Net просто плохо сочетаются. Но когда я писал вопрос, я использовал Ef core 2
3. Я использовал следующий подход, который, кажется, работает гладко:
if (command.Parameters["PATH_LIST"].Value is OracleRefCursor oracleRefCursor)
и если — да, то считывание с этого курсора… (PATH_LIST — это мой выходной параметр курсора)