如何使用ODP.NET按名称绑定查询参数?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (24)

我目前使用Oracle的ADO.NET提供程序(System.Data.OracleClient)。我知道它当然不是最好的Oracle提供商,它很快就会被弃用,我应该使用Oracle的ODP.NET。我仍然使用MS提供程序的原因是因为ODP.NET按位置绑定参数,而不是按名称。当在查询中使用多个参数时,这可能确实是PITA,因为必须小心以正确的顺序添加它们,这很容易导致错误发生。当你在同一个查询中多次使用相同的参数时,这也很烦人,例如:

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

使用ODP.NET,我必须添加两个参数OracleCommand,我认为这是愚蠢的...

ODP.NET OracleCommand有一个属性来改变默认行为:BindByName。当设置为true时,参数被名称绑定,这就是我想要的。不幸的是,这并不能真正帮助我,因为:

  • 它默认设置为false
  • 我几乎从来不使用混凝土ADO.NET类明确,我更喜欢使用ADO.NET 2.0抽象层(DbProviderFactoryDbConnectionDbCommand...),以减少连接到任何特定的RDBMS。所以我没有权利访问这个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;
    }
}

基于代码的数据访问应用程序块的在企业库

扫码关注云+社区