2010-02-01 74 views
6

由於System.Data.OracleClient庫已經是deprecated,我們正在將我們的代碼庫遷移到使用Oracle Data Provider for .NET(ODP.NET)。我們遇到的一個問題是,System.Data.OracleClient使用參數名稱綁定而不是按位置進行綁定,並且所有代碼都直接訪問System.Data.OracleClient.OracleCommand,而不是使用中間數據層。有沒有辦法強制OracleCommand.BindByName默認爲真ODP.NET?

由於代碼相當多,是否有一種簡單的方法可以強制ODP.NET OracleCommand.BindByName默認爲true,或者每次使用時都必須通過設置值?如果失敗,是否有一種簡單的方法在Visual Studio 2008中插入該行代碼?

+2

有沒有辦法通過設置'OracleCommand.BindByName'爲真默認。 –

+0

@Vadim K. - 這就是我害怕的東西,看起來我們需要一種方法來找到代碼中需要它的所有點。 – rjzii

+0

命令是存儲過程調用,還是僅僅是文本查詢?我只問,因爲如果他們是存儲過程調用,那麼BindByName將無法工作 - 您將不得不使用正確的參數順序。 –

回答

8

我知道這個線程是舊的,但我今天有同樣的問題,並認爲我會分享我的解決方案,以防別人有這個問題。由於OracleCommand是密封的(這很糟糕),我創建了一個封裝OracleCommand的新類,在實例化時將BindByName設置爲true。下面是實現的一部分:

public class DatabaseCommand 
{ 
    private OracleCommand _command = null; 

    public DatabaseCommand(string sql, OracleConnection connection) 
    { 
     _command = new OracleCommand(sql, connection) 
     { 
      BindByName = true 
     }; 
    } 

    public int ExecuteNonQuery() 
    { 
     return _command.ExecuteNonQuery(); 
    } 

    // Rest of impl removed for brevity 
} 

然後,所有我必須做清理的命令是做的OracleCommand搜索與DatabaseCommand和測試取代。

+0

不是我在寫這個問題時希望回覆的答案,但它是除了每次設置值之外最好的答案,它是您唯一的選擇。 – rjzii

+9

DatabaseCommand應該實現IDisposable,因爲OracleCommand是從實現此目的的DbCommand派生的。 – Sam

+0

還有沒有比這更好的解決方案?每個Oracle的答案似乎都涉及到創建某種墊片來彌補Oracle客戶端缺陷。 – EKW

0

添加部分類爲您的TableAdapter,並添加方法或屬性,只要你想,有了這個代碼:

 for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1)) 
     { 
      if ((this.CommandCollection[i] != null)) 
      { 
       ((global::Oracle.DataAccess.Client.OracleCommand)(this.CommandCollection[i])).BindByName = value; 
      } 
     } 
12

我沒有嘗試,但

我見過類似的東西

cmd.GetType().GetProperty("BindByName").SetValue(cmd,true,null);」 在PetaPoco.cs文件中。

也許它可以幫助。

+0

它當然解決了我的問題。 –

+1

這也允許使用命令而不必依賴於Oracle特定的數據對象。 –

4

我不得不移植ASPX代碼Oracle.DataAcees.Client後SqlDataSource的更新同樣的問題命令,並通過在SqlDataSource的OnUpdating處理器改變OracleCommand.BindByName財產這樣的解決了這個問題:

protected void SqlDataSource_Updating(object sender, SqlDataSourceCommandEventArgs e) 
{ 
    Oracle.DataAccess.Client.OracleCommand b_OracleCommand = 
        (Oracle.DataAccess.Client.OracleCommand)e.Command; 
    b_OracleCommand.BindByName = true; 
} 
+0

這是唯一明智的方式來做到這一點,而不必重構和更改一堆代碼。 – Gaui

-4

您可以使用此

using (var connection = new OracleConnection(connectionString)) 
     { 
      connection.Open(); 
      var cmd = connection.CreateCommand(); 
      cmd.CommandText = cmdText; 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.BindByName = true; 

      //Do something 

      cmd.ExecuteNonQuery(); 
     } 
+4

-1這個答案表明對問題實際上是什麼缺乏理解。 – rjzii

-2

爲了減少碼

VB.NET

#線
Dim command As OracleCommand = New OracleCommand(query, connection) With {.CommandType = CommandType.StoredProcedure, .BindByName = True} 

C#

OracleCommand command = new OracleCommand(query, connection) { CommandType = CommandType.StoredProcedure, BindByName = true }; 
0

我解決了這個問題,設置BindByName財產在SqlDataSource Updating事件的處理程序:

protected void SqlDataSource1_Updating(object sender, SqlDataSourceCommandEventArgs e) 
{ 
    ((Oracle.ManagedDataAccess.Client.OracleCommand)e.Command).BindByName = true; 
    // ... 
} 
相關問題