2013-11-21 22 views
7

Secondo la documentazione Microsoft su Configuring Parameters, "i provider di dati .NET Framework gestiscono la denominazione e la specifica di parametri e segnaposto di parametri in modo diverso".Come posso creare parametri SQL generici in .NET?

  • System.Data.SqlClient utilizza parametri con nome nel formato @parametername
  • System.Data.OleDb e System.Data.Odbc uso indicatori di parametro posizionali indicati da un punto interrogativo (?)
  • System.Data.OracleClient utilizza parametri con nome in formato :parmname (o parmname)

Sto scrivendo i metodi per restituire SQL che verrà utilizzato per le istruzioni parametrizzate. Se utilizzo SQL standard, queste istruzioni dovrebbero essere trasferibili su un'ampia varietà di database. Come posso creare parametri generalmente validi senza dispersione di dubbi dal fornitore di dati ai componenti SQL?

+0

Non penso che sono molto diversi. OleDb può identificare '@ campo'. È un tipo di universale. Oracle dovrebbe andare bene anche con esso. Ora, quando si aggiunge il parametro all'oggetto comando, è possibile evitare completamente il prefisso '@ field' e aggiungere semplicemente' field'. – nawfal

+0

PostGre va bene anche con @field. –

risposta

1

Basta evitare la @ e using System.Data.SqlClient /System.Data.OracleClient

Btw, se lo vuoi portatile, utilizzare uno o System.Data.IDbCommand System.Data.Common.DbCommand

Se si utilizza l'interfaccia o la classe astratta è una questione di gusti.
L'interfaccia è più corretta, la classe astratta ha tuttavia alcuni metodi aggiuntivi che non sono disponibili nell'interfaccia (ad esempio DataReader.HasRows). Ho usato l'interfaccia, ma in modo retrospettivo, si è trattato di un errore. Avrei dovuto usare invece la classe astratta (System.Data.Common.DbAnything invece di System.Data.IAnything).

È possibile scrivere un metodo di estensione "AddParameter" a questi oppure è possibile trasformare il DAL in una classe astratta e aggiungere un metodo AddParameter, in cui è possibile sovrascrivere il nome della variabile per l'istanza rispettiva.

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> 


} 

E poi sovrascrivere nel rispettivo fornitore:

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. 

} 

ed è possibile creare un rispettivo un'istanza di classe con la lettura provider nella voce di connessione stringa di web.config.

PS: System.Data.OracleClient è deprecato, utilizzare ODP.NET (ancora avete bisogno del OracleClient native DLL da Oracle installati [scaricabile])