17

我目前正在为 Oracle ( System.Data.OracleClient) 使用 Microsoft ADO.NET 提供程序。我知道它肯定不是最好的 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.NETOracleCommand具有更改该默认行为的属性:BindByName. 当设置为true时,参数由名称绑定,这就是我想要的。不幸的是,这并没有真正帮助我,因为:

  • 默认设置为 false
  • 我几乎从不明确使用具体的 ADO.NET 类,我更喜欢使用 ADO.NET 2.0 抽象层(、、、DbProviderFactory... DbConnectionDbCommand来减少与任何特定 RDBMS 的耦合。因此,除非我明确地转换为 ,否则我无权访问该BindByName属性,从而OracleCommand失去所有好处或抽象。
  • 使用 ASP.NET SqlDataSource 时,我自己不创建 DbCommand,因此我没有机会设置BindByName为 true(我可以在 Selecting 事件中执行此操作,但为每个执行此操作确实很痛苦SqlDataSource...)

我应该如何处理这个问题?BindByNameByDefault某处有设置吗?(我没有找到类似的东西,但我可能错过了......)

4

3 回答 3

7

我认为您可以创建自己的提供程序,使用您要使用的默认值。您可以通过从 odp.net 继承所有类来轻松创建该提供程序,只需调整一些属性,如 BindByName。

DbProviderfactory 将创建您的类而不是普通的 odp.net 类。

于 2009-06-26T09:19:55.340 回答
4

使用间接和继承!如果您通过抽象数据库类执行数据访问,则需要数据库实现句柄参数绑定。

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;
    }
}

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

于 2009-07-28T20:09:25.133 回答
1

至于 Oracle 的 Microsoft ADO .NET 提供程序的终止:

  • 我将继续使用它而不是 ODP .NET,您的问题只是它的众多问题之一。而且,它仍然可以在 .NET 4.0 中使用,尽管不受支持。
  • 如果 Oracle 设法使此提供程序无法使用,我可能会选择商业替代方案,例如Oracle 的DataDirect ADO.NET 数据提供程序或Oracle 的dotConnect,它们完全集成到 ADO .NET 框架中。顺便说一下,他们已经支持实体框架(我相信甲骨文表示 ODP .NET 不会)。

ODP .NET 已经占用了我太多时间。

于 2009-06-26T12:17:51.640 回答