Есть ли способ заставить OracleCommand.BindByName быть истинным по умолчанию для ODP.NET?

Поскольку библиотека System.Data.OracleClient была устарело, мы находимся в процесс миграции нашей базы кода для использования Oracle Data Provider для .NET (ODP.NET) вместо этого. Одна из проблем, с которыми мы столкнулись, заключается в том, что System.Data.OracleClient использует привязку имени параметра, а не привязку по позиции, и весь код напрямую обращается к System.Data.OracleClient.OracleCommand вместо использования промежуточного уровня данных.

Поскольку кода довольно много, есть ли простой способ заставить ODP.NET OracleCommand.BindByName быть истинным по умолчанию, или мы должны проходить и устанавливать значение каждый раз, когда оно используется? Если это не удается, есть ли простой способ вставить эту строку кода в Visual Studio 2008?


person rjzii    schedule 01.02.2010    source источник
comment
Невозможно установить для OracleCommand.BindByName значение true по умолчанию.   -  person Vadim K.    schedule 01.02.2010
comment
@Vadim K. - Это то, чего я боялся, похоже, нам нужен способ найти все места в коде, которые в этом нуждаются.   -  person rjzii    schedule 01.02.2010
comment
Являются ли команды вызовами хранимых процедур или просто текстовыми запросами? Я спрашиваю только потому, что если это вызовы хранимых процедур, то BindByName все равно не будет работать - вам придется использовать правильный порядок параметров.   -  person Igby Largeman    schedule 24.03.2010
comment
@Charles M - Все это текстовые запросы.   -  person rjzii    schedule 25.03.2010
comment
Если вам нужен еще более любопытный вариант Oracle по умолчанию, подождите, пока вы не попытаетесь прочитать ДОЛГО! Предлагаем также всегда устанавливать InitialLONGFetchSize = -1.   -  person Sam    schedule 28.09.2011


Ответы (7)


Я знаю, что эта ветка устарела, но сегодня у меня была такая же проблема, и я подумал, что поделюсь своим решением, если у кого-то еще будет эта проблема. Поскольку OracleCommand запечатан (что отстой), я создал новый класс, который инкапсулирует OracleCommand, установив для BindByName значение true при создании экземпляра. Вот часть реализации:

public class DatabaseCommand
{
    private OracleCommand _command = null;

    public DatabaseCommand(string sql, OracleConnection connection)
    {
        _command = new OracleCommand(sql, connection)
        {
            BindByName = true
        };
    }

    public int ExecuteNonQuery()
    {
        return _command.ExecuteNonQuery();
    }

    // Rest of impl removed for brevity
}

Затем все, что мне нужно было сделать для очистки команд, - это выполнить поиск OracleCommand, заменить его на DatabaseCommand и проверить.

person BrandonZeider    schedule 20.04.2011
comment
Это не тот ответ, на который я надеялся, когда писал вопрос, но он лучший в этом отношении, кроме того, что каждый раз настраиваете значение самостоятельно, это единственный вариант, который у вас есть. - person rjzii; 20.09.2011
comment
DatabaseCommand должен реализовывать IDisposable, поскольку OracleCommand является производным от DbCommand, который это реализует. - person Sam; 28.09.2011
comment
Нет ли лучшего решения, чем это? Кажется, что каждый ответ Oracle предполагает создание какой-то прокладки, чтобы компенсировать недостатки клиента Oracle. - person EKW; 14.02.2018

Я не пробовал, но,

Я видел что-то вроде

«cmd.GetType().GetProperty("BindByName").SetValue(cmd,true,null);» в файле PetaPoco.cs.

Может, это поможет.

person user925169    schedule 02.09.2011
comment
Это также позволяет работать с командами без зависимости от конкретных объектов данных Oracle. - person Richard Collette; 20.06.2013
comment
Проверено и работает. Спасибо. Это низменный грязный позор, что приходится прибегать к черной магии отражения, чтобы получить поведение, которое должно было присутствовать по умолчанию. Я хочу, чтобы они выставили параметр BindByName в строке подключения. - person Ant_222; 10.07.2020

У меня была такая же проблема с командами обновления SqlDataSource после переноса кода ASPX в Oracle.DataAcees.Client и я решил ее, изменив свойство OracleCommand.BindByName в обработчике SqlDataSource OnUpdating следующим образом:

protected void SqlDataSource_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
    Oracle.DataAccess.Client.OracleCommand b_OracleCommand = 
                  (Oracle.DataAccess.Client.OracleCommand)e.Command;
    b_OracleCommand.BindByName = true;
}
person Bore    schedule 19.12.2012
comment
Это единственный разумный способ сделать это без рефакторинга и изменения кучи кода. - person Gaui; 21.07.2014

С Oracle.ManagedDataAccess.Client вы можете настроить в app.config:

<oracle.manageddataaccess.client>
<version number="*">
  <dataSources>
    <dataSource alias="SampleDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))) " />
  </dataSources>
  <settings>
    <setting name="BindByName" value="True"/>
  </settings>
</version></oracle.manageddataaccess.client>
person Sadao    schedule 26.08.2019

Добавьте частичный класс для вашего TableAdapter и добавьте метод или свойство, как вы хотите, с помощью этого кода:

        for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1))
        {
            if ((this.CommandCollection[i] != null))
            {
                ((global::Oracle.DataAccess.Client.OracleCommand)(this.CommandCollection[i])).BindByName = value;
            }
        }
person DerSkythe    schedule 25.06.2011

Я решил эту проблему, установив свойство BindByName в обработчике события SqlDataSource Updating:

protected void SqlDataSource1_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
    ((Oracle.ManagedDataAccess.Client.OracleCommand)e.Command).BindByName = true;
    // ...
}
person ARoller    schedule 19.04.2016

Чтобы сократить # строк кода

VB.NET

Dim command As OracleCommand = New OracleCommand(query, connection) With {.CommandType = CommandType.StoredProcedure, .BindByName = True}

C#

OracleCommand command = new OracleCommand(query, connection) { CommandType = CommandType.StoredProcedure, BindByName = true };
person Glenn    schedule 04.05.2014