Есть ли способ заставить OracleCommand.BindByName быть истинным по умолчанию для ODP.NET?
Поскольку библиотека System.Data.OracleClient устарела, мы находимся в процессе миграции нашей кодовой базы для использования Oracle Data Provider for.NET (ODP.NET). Одна из проблем, с которой мы столкнулись, заключается в том, что System.Data.OracleClient использует привязку имени параметра, а не привязку по позиции, и весь код напрямую обращается к System.Data.OracleClient.OracleCommand, а не к использованию промежуточного уровня данных.
Поскольку кода довольно много, существует ли простой способ заставить ODP.NET OracleCommand.BindByName быть истинным по умолчанию, или мы должны проходить и устанавливать значение каждый раз, когда оно используется? В противном случае, есть ли простой способ вставить эту строку кода в Visual Studio 2008?
6 ответов
Я знаю, что эта ветка старая, но у меня была та же проблема сегодня, и я решил поделиться своим решением на случай, если кто-то еще столкнется с этой проблемой. Поскольку 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 и протестировать.
Я не пробовал это, но,
Я видел что-то вроде
"cmd.GetType().GetProperty("BindByName").SetValue(cmd,true,null);
"в файле PetaPoco.cs.
Может быть, это может помочь.
С 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>
У меня была та же проблема с командами обновления 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;
}
Я решил эту проблему, установив свойство BindByName в обработчике события SqlDataSource Updating:
protected void SqlDataSource1_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
((Oracle.ManagedDataAccess.Client.OracleCommand)e.Command).BindByName = true;
// ...
}
Добавьте частичный класс для вашего 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;
}
}
Чтобы уменьшить количество строк кода
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 };