代码之家  ›  专栏  ›  技术社区  ›  Thomas Levesque

用odp.net按名称绑定查询参数

  •  17
  • Thomas Levesque  · 技术社区  · 17 年前

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

    • 默认设置为假
    • 我几乎从不显式地使用具体的ADO.NET类,我更喜欢使用ADO.NET 2.0抽象层。( DbProviderFactory , DbConnection , DbCommand …)以减少对任何特定RDBMS的耦合。所以我无法访问 宾德尼亚梅 属性,除非我显式强制转换为 奥拉克曼 失去所有的利益或抽象。
    • 使用ASP.NET sqldatasource时,我不会自己创建dbcommand,因此我没有机会设置 宾德尼亚梅 为true(我可以在选择事件中执行此操作,但对每个sqldatasource执行此操作确实很困难…)

    我该如何处理这个问题?有没有 BindByNameByDefault 在某个地方?(我没有找到那样的东西,但我可能错过了……)

    3 回复  |  直到 15 年前
        1
  •  7
  •   Theo    17 年前

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

    dbProviderFactory将创建类,而不是普通的odp.net类。

        2
  •  4
  •   Anthony Mastrean PavanDevarakonda    16 年前

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

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

    代码基于 Data Access Application Block Enterprise Library .

        3
  •  1
  •   Mac    15 年前

    关于终止Microsoft ADO.NET Provider for Oracle:

    • 我将继续使用它而不是odp.net,您的问题只是其中众多问题之一。尽管不受支持,但它仍然可以在.NET 4.0中使用。
    • 如果Oracle设法使此提供程序不可用,我可能会选择一种商业替代方案,例如 DataDirect ADO.NET Data Provider for Oracle dotConnect for Oracle 完全集成到ADO.NET框架中。顺便说一下,他们已经支持实体框架(我相信Oracle声明odp.net不会)。

    odp.net已经占用了我太多的时间。