簡體   English   中英

使用ODP.NET按名稱綁定查詢參數

[英]Binding query parameters by name with ODP.NET

我目前正在使用Oracle的Microsoft 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(我可以在Selecting事件中執行它,但實際上這樣做真的很痛苦)每個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;
    }
}

基於企業庫中數據訪問應用程序塊的代碼。

至於停止使用Oracle的Microsoft ADO .NET提供程序:

  • 我將繼續使用它而不是ODP .NET,你的問題只是它的眾多問題之一。 盡管如此,它仍將在.NET 4.0中可用,但不受支持。
  • 如果Oracle設法使此提供程序無法使用,我可能會使用商業替代方案,例如DataDirect ADO.NET Data Provider for OracledotConnect for Oracle ,它們完全集成到ADO .NET框架中。 順便說一下,他們已經支持實體框架了(我相信Oracle聲稱ODP .NET不會)。

ODP .NET已經占用了我太多的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM