2013-11-21 13 views
7

Theo tài liệu của Microsoft trên Configuring Parameters, "các nhà cung cấp dữ liệu .NET Framework xử lý đặt tên và chỉ định thông số và trình giữ chỗ thông số khác nhau".Làm cách nào để tạo các tham số SQL chung trong .NET?

  • System.Data.SqlClient sử dụng tên thông số trong định dạng @parametername
  • System.Data.OleDbSystem.Data.Odbc sử dụng các marker tham số vị trí được chỉ định bởi một dấu chấm hỏi (?)
  • System.Data.OracleClient sử dụng thông số có tên theo định dạng :parmname (hoặc tên parmname)

Tôi đang viết các phương thức để trả về SQL sẽ được sử dụng cho các câu lệnh được tham số hóa. Nếu tôi sử dụng SQL tiêu chuẩn, các câu lệnh này nên được chuyển sang nhiều cơ sở dữ liệu khác nhau. Làm cách nào tôi có thể tạo các tham số thường hợp lệ mà không làm rò rỉ các mối quan tâm từ nhà cung cấp dữ liệu đến các thành phần SQL?

+0

Tôi không nghĩ rằng chúng rất khác nhau. OleDb có thể xác định '@ field'. Loại phổ quát của nó. Oracle cũng tốt với nó. Bây giờ khi thêm tham số vào đối tượng command, bạn hoàn toàn có thể tránh tiền tố '@ field' và chỉ cần thêm' field'. – nawfal

+0

PostGre cũng ổn với @field. –

Trả lời

1

Chỉ cần tránh @ và using System.Data.SqlClient /System.Data.OracleClient

Btw, nếu bạn muốn nó di động, sử dụng một trong hai System.Data.IDbCommand hoặc System.Data.Common.DbCommand

Cho dù bạn sử dụng giao diện hoặc lớp trừu tượng là vấn đề về hương vị.
Giao diện thích hợp hơn, lớp trừu tượng tuy nhiên có một vài phương thức bổ sung không có sẵn trong giao diện (ví dụ: DataReader.HasRows). Tôi đã sử dụng giao diện, nhưng nhìn lại, đó là một lỗi. Tôi nên sử dụng lớp trừu tượng thay thế (System.Data.Common.DbAnything thay vì System.Data.IAnything).

Bạn có thể viết phương thức mở rộng "AddParameter" vào các lớp này, hoặc bạn có thể biến DAL của bạn thành lớp trừu tượng và thêm phương thức AddParameter, tại đây bạn có thể ghi đè tên biến cho trường hợp respecitive.

public abstract class cDAL 
{ 


    // From Type to DBType 
    protected virtual System.Data.DbType GetDbType(Type type) 
    { 
     // http://social.msdn.microsoft.com/Forums/en/winforms/thread/c6f3ab91-2198-402a-9a18-66ce442333a6 
     string strTypeName = type.Name; 
     System.Data.DbType DBtype = System.Data.DbType.String; // default value 

     try 
     { 
      if (object.ReferenceEquals(type, typeof(System.DBNull))) 
      { 
       return DBtype; 
      } 

      if (object.ReferenceEquals(type, typeof(System.Byte[]))) 
      { 
       return System.Data.DbType.Binary; 
      } 

      DBtype = (System.Data.DbType)Enum.Parse(typeof(System.Data.DbType), strTypeName, true); 

      // Es ist keine Zuordnung von DbType UInt64 zu einem bekannten SqlDbType vorhanden. 
      // http://msdn.microsoft.com/en-us/library/bbw6zyha(v=vs.71).aspx 
      if (DBtype == System.Data.DbType.UInt64) 
       DBtype = System.Data.DbType.Int64; 
     } 
     catch (Exception) 
     { 
      // add error handling to suit your taste 
     } 

     return DBtype; 
    } // End Function GetDbType 


    public virtual System.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue) 
    { 
     return AddParameter(command, strParameterName, objValue, System.Data.ParameterDirection.Input); 
    } // End Function AddParameter 


    public virtual System.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue, System.Data.ParameterDirection pad) 
    { 
     if (objValue == null) 
     { 
      //throw new ArgumentNullException("objValue"); 
      objValue = System.DBNull.Value; 
     } // End if (objValue == null) 

     System.Type tDataType = objValue.GetType(); 
     System.Data.DbType dbType = GetDbType(tDataType); 

     return AddParameter(command, strParameterName, objValue, pad, dbType); 
    } // End Function AddParameter 


    public virtual System.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue, System.Data.ParameterDirection pad, System.Data.DbType dbType) 
    { 
     System.Data.IDbDataParameter parameter = command.CreateParameter(); 

     if (!strParameterName.StartsWith("@")) 
     { 
      strParameterName = "@" + strParameterName; 
     } // End if (!strParameterName.StartsWith("@")) 

     parameter.ParameterName = strParameterName; 
     parameter.DbType = dbType; 
     parameter.Direction = pad; 

     // Es ist keine Zuordnung von DbType UInt64 zu einem bekannten SqlDbType vorhanden. 
     // No association DbType UInt64 to a known SqlDbType 

     if (objValue == null) 
      parameter.Value = System.DBNull.Value; 
     else 
      parameter.Value = objValue; 

     command.Parameters.Add(parameter); 
     return parameter; 
    } // End Function AddParameter 


    public virtual T GetParameterValue<T>(System.Data.IDbCommand idbc, string strParameterName) 
    { 
     if (!strParameterName.StartsWith("@")) 
     { 
      strParameterName = "@" + strParameterName; 
     } 

     return InlineTypeAssignHelper<T>(((System.Data.IDbDataParameter)idbc.Parameters[strParameterName]).Value); 
    } // End Function GetParameterValue<T> 


} 

Và sau đó ghi đè lên nó trong các nhà cung cấp tương ứng:

public class cOleDb : cDAL 
{ 




    public overrideSystem.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue) 
    { 
     strParameterName = "?"; 
     return AddParameter(command, strParameterName, objValue, System.Data.ParameterDirection.Input); 
    } // End Function AddParameter 


    // Etc. 

} 

Và bạn có thể tạo ra một cá thể của lớp tương ứng bằng cách đọc provider trong mục kết nối chuỗi web.config.

PS: System.Data.OracleClient bị phản đối, sử dụng ODP.NET (bạn vẫn cần OracleClient mẹ đẻ dll từ Oracle cài đặt [tải về miễn phí])

Các vấn đề liên quan