Привязка параметров запроса по имени с помощью ODP.NET

StackOverflow https://stackoverflow.com/questions/1046632

  •  20-08-2019
  •  | 
  •  

Вопрос

В настоящее время я использую поставщика Microsoft ADO.NET для Oracle (System.Data.OracleClient).Я знаю, что это, безусловно, не лучший доступный поставщик Oracle и что он скоро будет признан устаревшим, вместо этого я должен использовать Oracle ODP.NET.Причина, по которой я все еще использую MS provider, заключается в том, что ODP.NET привязывает параметры по положению, не по имени.Это действительно может быть проблемой, когда вы используете много параметров в запросе, потому что вы должны быть осторожны, добавляя их в правильном порядке, что может легко привести к ошибкам.Это также раздражает, когда вы используете один и тот же параметр несколько раз в одном запросе, например :

SELECT A,B,C FROM FOO WHERE X = :PARAM_X OR :PARAM_X = 0

С помощью ODP.NET я должен добавить два параметра к OracleCommand, что я считаю глупым...

ODP.NET 's OracleCommand имеет свойство изменять это поведение по умолчанию : BindByName.Когда установлено значение true, параметры привязываются по имени, чего я и хочу.К сожалению, это мне на самом деле не помогает, потому что :

  • По умолчанию для него установлено значение false
  • Я почти никогда не использую конкретные ADO.NET классы явно, я предпочитаю использовать ADO.NET уровень абстракции 2.0 (DbProviderFactory, DbConnection, DbCommand...) чтобы уменьшить привязку к любой конкретной СУБД.Так что у меня нет доступа к BindByName свойство, если только я явно не приведу его к OracleCommand, теряя все преимущества или абстракцию.
  • При использовании ASP.NET SqlDataSource я сам не создаю DbCommand, поэтому у меня нет возможности установить BindByName в true (я мог бы сделать это в событии выбора, но это действительно сложно сделать для каждого SqlDataSource ...)

Как я должен справиться с этой проблемой ?Есть ли какой-нибудь BindByNameByDefault сидишь где - нибудь ?(Я не нашел ничего подобного, но, возможно, я это пропустил ...)

Это было полезно?

Решение

Я думаю, вы можете создать своего собственного провайдера, который будет использовать настройки по умолчанию, которые вы хотите использовать.Вы можете легко создать этого поставщика, унаследовав все классы от odp.net, просто настроив некоторые свойства, такие как BindByName.

DbProviderfactory создаст ваши классы вместо обычных классов odp.net.

Другие советы

Используйте косвенность и наследование!Если вы выполняете доступ к данным через абстрактный класс базы данных, потребуется привязка параметра дескриптора реализации базы данных.

public abstract class Database
{
    private readonly DbProviderFactory factory;

    protected Database(DbProviderFactory factory)
    {
        this.factory = factory;
    }

    public virtual DbCommand CreateCommand(String commandText)
    {
        return CreateCommand(CommandType.Text, commandText);
    }

    public virtual DbCommand CreateCommand(CommandType commandType, String commandText)
    {
        DbCommand command = factory.CreateCommand();
        command.CommandType = commandType;
        command.Text = commandText;
        return command;
    }

    public virtual void BindParametersByName(DbCommand command)
    {

    }
}

И выберите создание конкретной реализации Oracle, которая переопределяет создание команд по умолчанию или предоставляет возможность привязывать параметры по имени.

public class OracleDatabase : Database
{
    public OracleDatabase()
        : base(OracleClientFactory.Instance)
    {

    }

    public override DbCommand CreateCommand(CommandType commandType, String commandText)
    {
        DbCommand command = base.CreateCommand(commandType, commandText);
        BindParametersByName(command);
        return command;
    }

    public override void BindParametersByName(DbCommand command)
    {
        ((OracleCommand)command).BindByName = true;
    }
}

Код, основанный на Прикладной блок доступа к данным в Корпоративная библиотека.

Что касается прекращения работы поставщика Microsoft ADO .NET для Oracle :

  • Я буду продолжать использовать его вместо ODP .NET, поскольку ваша проблема является лишь одной из многочисленных проблем, связанных с ним.И по ходу дела он по-прежнему будет доступен в .NET 4.0, хотя и не поддерживается.
  • Если Oracle удастся сделать этого провайдера непригодным для использования, я, вероятно, выберу коммерческую альтернативу, такую как DataDirect ADO.NET Поставщик данных для Oracle или dotConnect для Oracle, которые полностью интегрируются в ADO .NET Framework.И, кстати, они уже поддерживают Entity Framework (я полагаю, Oracle заявила, что ODP .NET этого не сделает).

ODP .NET и так отнял у меня слишком много времени.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top