2016-03-02 5 views
1

Прежде чем я начну, советую вам сделать глубокий вдох и понять, это очень длинный вопрос и проблема 3-4 в одном контексте. Так что терпение при чтении. (напишите в комментарии, если вам что-нибудь понадобится, образец кода или что-то еще, поскольку я серьезно ищу решение).Проблемы с Oracle .NET DATA Provider - Ищем другой вариант

Недавно я работал с клиентом, и он хотел иметь базу данных приложений в Oracle. Приложение было построено на основе ASP.NET MVC.

Мы выбираем Oracle 11g Экспресс для среды разработки, и клиент подтвердил то же самое. Мы решили пойти с ODAC 32bit .NET Provider, который поддерживает ORM (EF). Сначала мы провели пробный случай внедрения CRUD-операции, и все было хорошо. Затем мы приступили к разработке требований клиента. Через 2-3 месяца продукт был готов к поставке. Так что до сих пор все отлично работало на ASP.NET и Oracle 11g. Когда мы отправились на развертывание и UAT, мы узнали, что у клиента есть oracle 9i для его существующего ERP, который не соответствует версии, которую мы разработали. Поэтому мы искали в Интернете для проверки того, совместим ли тот же поставщик ODAC с Oracle 9i. Мы нашли ссылки, в которых упоминалось, что они совместимы с Oracle 9i.

Мы просто мигрировали базы данных в Oracle 9i сервера, изменение EF модели соответственно и найдены следующие вопросы:

1. Сделка не была автоматически совершено!

using (TransactionScope transaction = new TransactionScope()) 
{ 
    // some code written here 
} 

Тот же самый код работает с 11g и когда переехал в Oracle 9i он перестал working.Transactions не автоматически совершать после завершения использования заявления. Мы намеренно написали transaction.commit(); в блоке использования, и он начал работать.

Ожидается ли такое поведение?

2. Проблема с VARCHAR2 datatype и поставщиком ODP NET. Мы создали несколько хранимых процедур в базе данных, имеющих Varchar2 и другие типы db в качестве параметра. При доступе к этой хранимой процедуре с использованием стиля ADO.NET (OracleConnection, OracleCommand и OracleParameter) мы узнали, что параметры, имеющие тип данных VARCHAR2, усекают данные, даже если данные, переданные параметру, имеют меньший размер, чем таблица столбец. Он просто случайно удаляет количество символов с конца. Problem is also logged here in oracle forum

Мы не смогли найти решение этого вопроса.

3. Ограничение размера встроенного запроса (без символов). Для решения проблемы, упомянутой в № 2, мы поняли, что мы должны преобразовать эту хранимую процедуру в встроенный запрос и вызвать тех, кто использует ADO.NET (старый стиль во время школьных кодировок)! Мы преобразовали все наши хранимые процедуры в строковые сценарии и написали как следующие:

OracleCommand command=new OracleCommand("Select * from something",Connection); 

И использовал ту же технику для других операторов DML. Теперь все работает нормально, мы проводили UAT, и мы сделали приложение вживую. Через 10-15 дней мы обнаружили странную проблему.Если запрос (встроенный запрос) имеет размер более 4000 символов, тогда сервер Oracle генерирует исключение, заявляя, что «Query слишком длинный для выполнения» (я не помню исключение или сообщение точно, но оно было похоже на то, что я написал) , Мы взяли образцы данных в среду разработки и отлаживали код и узнали, что размер SQL-запроса слишком длинный, длиннее 32000 - 64000 символов! Мы знали, что решение для этого было таким же: «Если мы сможем как-то правильно вызвать хранимые процедуры!» Но мы не можем, поскольку у нас нет выбора.

В качестве решения мы воссоздали эту хранимую процедуру в базе данных и назвали эту встроенную встроенную процедуру!

OracleCommand command=new OracleCommand("BEGIN ProceduretoCall(Param1,Param2); END;",Connection); 

И он работает с тех пор.

С выше проблем в виду,

  1. Я не могу назвать хранимой процедуры ASP.NET обычным способом (CommandType.StoredProcedure) # проблемно-1 в выше
  2. Я не способный возвращать любые данные или скалярное значение или возвращаемое значение из хранимой процедуры после вставки или обновления. # проблема-3 выше
  3. Я не могу использовать транзакции на уровне кода. (Он продолжает говорить, что распределенная транзакция инициализирована, но на самом деле у меня нет распределенной транзакции вообще!)

Почему все вышло в конце после Go Live? Это был почти кошмар вопросов с оракулом, который я решал в течение месяца, один за другим, и это заставило меня думать

Является ли инструмент ODP.NET/ ODAC действительно надежным?

Если нет, то какой другой вариант я могу использовать в зависимости от вашего опыта? (Пожалуйста, знайте, что ODBC также имеет аналогичную проблему с Oracle 9i).

На следующей неделе я с большей вероятностью буду работать над подобным проектом, и я подумал, что на этот раз я хочу быть готовым с лучшим подходом.

+1

Oracle 9i не поддерживается. Не следует разрабатывать новые приложения. –

+0

Вы должны разложить свой вопрос на куски. Этот вопрос неопровержимо. –

ответ

0

Я настоятельно рекомендую изолировать каждую из ваших точек как отдельный вопрос. Каждый из них специфичен и имеет свои собственные вопросы, и это будет беспорядок, сохраняя все это прямолинейно.

Во-вторых, я согласен с комментарием. Даже Oracle 10gR1, выпущенный в 2003 году, не поддерживается. Возможно, вам нужно принять часть ответственности, не задавая этот вопрос заранее, но я также не думаю, что вам небезосновательно утверждать, что они будут использовать поддерживаемую версию oracle.

Это сказал я возьму быстрый удар:

  1. TransactionScope никогда не autocommits. Вам нужно будет добавить transaction.Complete(). Единственное непредвиденное поведение, которое WAS совершает раньше.

  2. В упомянутой статье упоминается, что проблема устранена при перекомпиляции операций оракула и указывает набор исправлений оракула, который устраняет проблему. Если это так, я не считаю это проблемой odp.net. Если вы хотите, вы можете вставить как подпись proc, так и то, как вы добавляете параметр, чтобы увидеть, есть ли какие-то твики, которые вы можете попробовать. Но опять же, я бы опубликовал отдельный вопрос.

3.2 - Я не уверен, как вы все равно возвращаете скаляры - вам нужен рефкурсор для параметра, и я не уверен, как это изменит анонимный блок. Снова я думаю, вам нужно разместить больше своего кода, в частности, как вы отправляете параметры.

3.3 - TransactionScope автоматически преобразует из локальной транзакции в распределенное соединение, если транзакция включает в себя несколько соединений, даже если они относятся к одной и той же базе данных. Тем не менее, я не думаю, что эта функция была поддержана до 11g, и ранее все транзакции начались бы как распределенные. Тем не менее, я не уверен, что у меня даже была эта концепция, которая могла бы объяснить странную автоматическую фиксацию, которую вы видели.

ODP.net был полностью надежным для меня последние 7 лет. Тем не менее, я всегда запускал его против поддерживаемой версии oracle с достаточно современным патчем, установленным для этой версии.

+0

Я полностью понимаю и подумал о том, чтобы разделить эти вопросы на разные вопросы, но тогда контекст не может быть получен ... поскольку вы видите, что более поздние вопросы связаны друг с другом ... Oracle 9i не поддерживается? Он поддерживается, но он работает не так, как ожидалось. –

+0

Что касается других комментариев, TransactionScope делает автоматическое совершение, как говорит Microsoft, и это работает для меня с MSSQL. В справочной статье вы можете снова и снова проверить, что есть такие люди, как я, которые не смогли решить эту проблему даже после перекомпиляции пакета! (Ну, в моем случае у меня нет пакета, я не возражал при перекомпиляции моих процедур). Как я возвращал скаляры? С возвращаемыми значениями, как я делал в MSSQL, но поскольку хранимая процедура перестала работать, у меня не было выбора. –

+0

Я должен согласиться и перекрестно проверить пункт 3.3 (у меня есть несколько соединений для одной базы данных), так что это может быть одной из причин. Спасибо, что указали это! –

 Смежные вопросы

  • Нет связанных вопросов^_^