2012-04-13 74 views
0

我該如何進行參數化?將查詢轉換爲參數化的asp.net查詢

string query = ""; 

      query += " SELECT DistID FROM Distributor"; 
      query += " WHERE Username = '" + username_id.Text + "'"; 
      query += " AND Password = '" + password.Text + "'"; 

      GeneralFunctions.GetData(query); 

可以在這裏完成,還是必須在GetData方法內完成?

這裏有兩種方法:

public static DataTable GetData (string query) 
{ 
    SqlDataAdapter dataAdapter; 
    DataTable table; 

    try 
    { 
     dataAdapter = new SqlDataAdapter(query, GetConnectionString()); 
     table = new DataTable(); 

     dataAdapter.Fill(table); 
     return table; 
    } 
    catch (Exception ex) 
    { 
    } 
    finally 
    { 
     dataAdapter = null; 
     table = null; 
    } 

    return table; 
} 

public static string GetConnectionString() 
{ 
    string connectionString = ConfigurationManager.ConnectionStrings[ "CAPortalConnectionString" ].ConnectionString; 

    return connectionString; 
} 
+0

@Aristos我不知道DAL的是。這是一個對我來說是一個學習項目,即時通訊從傳統的asp到asp.net的飛躍。上面的代碼不是獲取sql數據和連接字符串的好例子嗎? – 2012-04-13 15:57:34

+0

這是一個很好的篩選通過谷歌和假設你認識好,99%的例子更像他想要改變的代碼:( – 2012-04-13 16:03:15

+0

@TonyHopkinson上面的代碼是不好的?它會如何變好? – 2012-04-13 16:06:51

回答

3

我建議你設計特定的方法來查詢數據庫,如:

public static int? GetDistID(string username, string password) 
{ 
    using (var conn = new SqlConnection(GetConnectionString())) 
    using (var cmd = conn.CreateCommand()) 
    { 
     conn.Open(); 
     cmd.CommandText = 
     @"SELECT 
       DistID 
      FROM 
       Distributor 
      WHERE 
       Username = @username 
      AND 
       Password = @password"; 
     cmd.Parameters.AddWithValue("@username", username); 
     cmd.Parameters.AddWithValue("@password", password); 
     using (var reader = cmd.ExecuteReader()) 
     { 
      if (!reader.Read()) 
      { 
       // no results found 
       return null; 
      } 
      return reader.GetInt32(reader.GetOrdinal("DistID")); 
     } 
    } 
} 

然後:

var distId = GeneralFunctions.GetDistID(username_id.Text, password.Text); 

不需要DataTables/Sets/Adapters。使用強類型對象。

+0

你能幫我理解它的一些部分嗎,比如'int?' 我也假設我將它放在我的'GeneralFunctions'中,並在我的登錄頁面上調用它,比如'GetDistID(username_id.Text,password.Text) ' '如果(reader.Read()) 認證 否則不進行身份驗證是。雖然它會返回null也許如果讀者!= null?' 我想我理解其餘的。 – 2012-04-13 15:56:07

+0

'int?'是可空的的別名,意思是可爲空的整數。我使用它,因爲在數據庫中找不到與用戶名和密碼匹配的記錄的情況下,函數可能返回null。如果該方法的簽名只是'int GetDistID()',則不能返回null,因爲Int32是一個值類型。當您調用'reader.Read()'時,它將讀取器推進到與您的條件相對應的數據庫中找到的下一行,並返回一個布爾值,指示是否有更多行。 – 2012-04-13 15:57:08

+0

有一個優點。如果你已經把doc文件放進去了,我會以其他人的身份登錄並給你另一個文件。 – 2012-04-13 16:00:07

1

使用SqlCommand對象,你可以這樣創建一個參數化查詢:

public object GetDistID(string username, string password) 
{ 
    using (var conn = new SqlConnection("...")) 
    { 
     using (var cmd = new SqlCommand("SELECT DistID FROM Distributor WHERE [email protected] AND [email protected]", conn)) 
     { 
      cmd.Connection.Open(); 
      cmd.Parameters.AddWithValue("@Username", username); 
      cmd.Parameters.AddWithValue("@Password", password);     
      return cmd.ExecuteScalar(); 
     } 
    } 
} 

如果這是對你有用,這裏是你可以使用一個類。它是對存儲過程量身定做的,但它應該是很容易的添加接受查詢的方法:

using System; 
using System.Data; 
using System.Data.SqlClient; 
using System.Configuration; 
using System.Web; 
using System.Xml; 
using System.Collections; 
using System.Collections.Specialized; 
using System.Collections.Generic; 
using System.Text; 

namespace NESCTC.Data 
{ 
    public class DataAccess : IDisposable 
    { 
     #region declarations 

     private SqlCommand _cmd; 
     private string _SqlConnString; 

     #endregion 

     #region constructors 

     public DataAccess(string ConnectionString) 
     { 
      _cmd = new SqlCommand(); 
      _cmd.CommandTimeout = 240; 
      _SqlConnString = ConnectionString; 
     } 

     #endregion 

     #region IDisposable implementation 

     ~DataAccess() 
     { 
      Dispose(false); 
     } 

     public void Dispose() 
     { 
      Dispose(true);    
     } 

     protected virtual void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       _cmd.Connection.Dispose(); 
       _cmd.Dispose(); 
      } 
     } 

     #endregion 

     #region data retrieval methods 

     public DataTable ExecReturnDataTable() 
     { 
      using (SqlConnection conn = new SqlConnection(this.ConnectionString)) 
      { 
       try 
       { 
        PrepareCommandForExecution(conn); 
        using (SqlDataAdapter adap = new SqlDataAdapter(_cmd)) 
        { 
         DataTable dt = new DataTable(); 
         adap.Fill(dt); 
         return dt; 
        } 
       } 
       catch 
       { 
        _cmd.Connection.Close(); 
        throw; 
       } 
       finally 
       { 
        _cmd.Connection.Close(); 
       } 
      } 
     }  

     public object ExecScalar() 
     { 
      using (SqlConnection conn = new SqlConnection(this.ConnectionString)) 
      { 
       try 
       { 
        PrepareCommandForExecution(conn); 
        return _cmd.ExecuteScalar(); 
       } 
       catch (Exception ex) 
       { 
        _cmd.Connection.Close(); 
        throw ex; 
       } 
       finally 
       { 
        _cmd.Connection.Close(); 
       } 
      } 
     }     

     #endregion 

     #region data insert and update methods 

     public void ExecNonQuery() 
     { 
      using (SqlConnection conn = new SqlConnection(this.ConnectionString)) 
      { 
       try 
       { 
        PrepareCommandForExecution(conn); 
        _cmd.ExecuteNonQuery(); 
       } 
       catch 
       { 
        _cmd.Connection.Close(); 
        throw; 
       } 
       finally 
       { 
        _cmd.Connection.Close(); 
       } 
      } 
     } 

     #endregion 

     #region helper methods 

     public void AddParm(string ParameterName, SqlDbType ParameterType, object Value) 
     { _cmd.Parameters.Add(ParameterName, ParameterType).Value = Value; } 

     private SqlCommand PrepareCommandForExecution(SqlConnection conn) 
     { 
      try 
      { 
       _cmd.Connection = conn; 
       _cmd.CommandType = CommandType.StoredProcedure; 
       _cmd.CommandTimeout = this.CommandTimeout; 
       _cmd.Connection.Open(); 

       return _cmd; 
      } 
      catch 
      { 
       _cmd.Connection.Close(); 
       throw; 
      } 
     } 

     #endregion 

     #region properties 

     public int CommandTimeout 
     { 
      get { return _cmd.CommandTimeout; } 
      set { _cmd.CommandTimeout = value; } 
     } 

     public string ProcedureName 
     { 
      get { return _cmd.CommandText; } 
      set { _cmd.CommandText = value; } 
     } 

     public string ConnectionString 
     { 
      get { return _SqlConnString; } 
      set { _SqlConnString = value; } 
     } 

     #endregion 
    } 
} 

您可以使用類是這樣的:

public object GetDistID(string username, string password) 
{ 
    using (var data = new DataAccess("ConnectionString")) 
    { 
     data.ProcedureName = "GetDistID"; 
     data.AddParm("@Username", SqlDbType.VarChar, username); 
     data.AddParm("@Password", SqlDbType.VarChar, password); 
     return data.ExecScalar(); 
    } 
} 
+0

哇,我希望我明白這一切是做得更好。我正在主演這部電影,如果我能理解它,我們會試着去使用它。非常感謝您的回答。 – 2012-04-13 16:17:44