2010-02-01 24 views
6

Vì thư viện System.Data.OracleClient đã được deprecated, chúng tôi đang trong quá trình di chuyển cơ sở mã của chúng tôi để sử dụng Oracle Data Provider for .NET (ODP.NET) thay thế. Một trong những vấn đề mà chúng tôi gặp phải là System.Data.OracleClient sử dụng tên tham số ràng buộc trái ngược với ràng buộc bởi vị trí và tất cả mã trực tiếp truy cập vào System.Data.OracleClient.OracleCommand như trái ngược với việc sử dụng lớp dữ liệu trung gian.Có cách nào để buộc OracleCommand.BindByName phải đúng theo mặc định cho ODP.NET không?

Vì có khá nhiều mã, có cách nào dễ dàng để buộc ODP.NET OracleCommand.BindByName là đúng theo mặc định hay chúng ta phải đi qua và đặt giá trị mỗi khi nó được sử dụng? Thất bại ở đó, là có một cách dễ dàng để chèn dòng mã trong Visual Studio 2008?

+2

Không có cách nào để thiết lập 'OracleCommand.BindByName' true bởi mặc định. –

+0

@Vadim K. - Đó là loại những gì tôi đã sợ, có vẻ như chúng ta cần một cách để tìm tất cả các điểm trong mã cần nó sau đó. – rjzii

+0

Các lệnh gọi thủ tục được lưu trữ hay chỉ là các truy vấn văn bản? Tôi chỉ hỏi vì nếu chúng được lưu trữ các cuộc gọi thủ tục, sau đó BindByName sẽ không hoạt động anyway - bạn sẽ phải sử dụng thứ tự tham số chính xác. –

Trả lời

8

Tôi biết chủ đề này là cũ, nhưng tôi đã có cùng một vấn đề ngày hôm nay và nghĩ rằng tôi sẽ chia sẻ giải pháp của tôi trong trường hợp người khác có vấn đề này. Kể từ khi OracleCommand được niêm phong (mà hút), tôi tạo ra một lớp mới đóng gói OracleCommand, thiết lập BindByName thành true trên instantiation. Đây là một phần của quá trình triển khai:

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 
} 

Sau đó, tất cả những gì tôi phải làm để tìm kiếm OracleCommand và thay thế bằng DatabaseCommand và kiểm tra.

+0

Không phải là câu trả lời tôi đã hy vọng trở lại khi tôi viết câu hỏi, nhưng nó là tốt nhất trong đó khác hơn là thiết lập giá trị cho mình mỗi lần, nó là lựa chọn duy nhất mà bạn có. – rjzii

+9

DatabaseCommand nên triển khai IDisposable, vì OracleCommand có nguồn gốc từ DbCommand thực hiện điều này. – Sam

+0

Vẫn chưa có giải pháp nào tốt hơn? Mỗi câu trả lời của Oracle dường như liên quan đến việc tạo ra một số loại shim để bù đắp cho sự thiếu hụt của khách hàng Oracle. – EKW

0

Thêm partial class cho TableAdapter của bạn, và thêm phương pháp, hoặc tài sản, như bạn muốn, với mã này:

 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

Tôi không thử nó nhưng,

Tôi đã thấy một cái gì đó như

"cmd.GetType().GetProperty("BindByName").SetValue(cmd,true,null);" trong tệp PetaPoco.cs.

Có thể nó có thể hữu ích.

+0

Nó chắc chắn đã giải quyết được vấn đề của tôi. –

+1

Điều này cũng cho phép làm việc với các lệnh mà không cần phải có sự phụ thuộc vào các đối tượng dữ liệu cụ thể của Oracle. –

4

tôi đã cùng một vấn đề với SqlDataSource Cập nhật lệnh sau porting mã ASPX để Oracle.DataAcees.Client và giải quyết nó bằng cách thay đổi sở hữu OracleCommand.BindByName trong handler SqlDataSource OnUpdating như thế này:

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

Đây là cách hợp lý duy nhất để thực hiện việc này mà không cần phải cấu trúc lại và thay đổi mã. – Gaui

-4

Bạn có thể sử dụng này

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 Câu trả lời này cho thấy sự thiếu hiểu biết về câu hỏi thực sự là gì. – rjzii

-2

Để giảm # dòng mã

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

tôi giải quyết thiết lập thuộc tính BindByName trong xử lý các sự kiện SqlDataSource Đang cập nhật vấn đề này:

protected void SqlDataSource1_Updating(object sender, SqlDataSourceCommandEventArgs e) 
{ 
    ((Oracle.ManagedDataAccess.Client.OracleCommand)e.Command).BindByName = true; 
    // ... 
} 
Các vấn đề liên quan