如何使用SQL参数从SQL Server获取数据集

我正在研究C#项目,我是这项技术的新手。

我想从SQL Server 2008中读取一些数据,然后编写以下代码

public User select(string username, string password) { string connection = ConfigurationManager.ConnectionStrings["lawyersDBConnectionString"].ConnectionString.ToString(); string sql = string.Format("select * from users where userName = '{0}' and password = '{1}'", username, password); SqlConnection con = new SqlConnection(); con.ConnectionString = connection; DataSet ds = new DataSet(); SqlDataAdapter da = new SqlDataAdapter(sql, con); User user = new User(); DataRow dr; try { da.Fill(ds); dr = ds.Tables[0].Rows[0]; user.Id = Convert.ToInt16(dr["userID"]); user.FirstName = (string)dr["firstName"]; user.LastName = (string)dr["lastName"]; user.Email = (string)dr["email"]; user.Username = (string)dr["userName"]; user.Password = (string)dr["password"]; user.type = (string)dr["type"]; return user; } catch (Exception ex) { return null; } }//end of select method 

但我读过一篇关于SQL注入的文章,我想使用SQL参数来避免这种情况,但我不知道如何。

这是对代码的简单修改。 未经测试,但实际上它包括在一次性对象周围添加using语句以及使用SqlCommand及其参数集合

 string connection = ConfigurationManager.ConnectionStrings ["lawyersDBConnectionString"].ConnectionString.ToString(); string sql = "select * from users where userName = @uname and password = @pwd"; DataSet ds = new DataSet(); using(SqlConnection con = new SqlConnection(connection)) using(SqlCommand cmd = new SqlCommand(sql, con)) { con.Open(); cmd.Parameters.AddWithValue("@uname", username); cmd.Parameters.AddWithValue("@pwd", password); using(SqlDataAdapter da = new SqlDataAdapter(cmd)) { User user = new User(); DataRow dr; da.Fill(ds); dr = ds.Tables[0].Rows[0]; user.Id = Convert.ToInt16(dr["userID"]); user.FirstName = (string)dr["firstName"]; user.LastName = (string)dr["lastName"]; user.Email = (string)dr["email"]; user.Username = (string)dr["userName"]; user.Password = (string)dr["password"]; user.type = (string)dr["type"]; return user; } } 

请注意命令文本如何不直接包含用户和密码的字符串,而是一个简单的参数占位符(@uname and @pwd) 。 将参数添加到SqlCommand集合时,这些占位符称为参数名称。

看看检索到的数据的用法我强烈建议你看看像Dapper这样的简单ORM工具可以直接翻译User对象中的所有代码

有趣的是,String.Format的工作方式与SQL参数没有太大区别。 唯一真正的区别是你指定了每个参数的数据类型,它允许SQLCommand正确地清理(读取:阻止sql注入)用户的输入。

以下是如何更改代码以使用SQL参数的示例。

 using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlCommand command = new SqlCommand("select * from users where userName = @pUsername and password = @pPassword", connection)) { command.Parameters.Add(new SqlParameter("pUsername", username)); command.Parameters.Add(new SqlParameter("pPassword", password)); DataSet ds = new DataSet(); SqlDataAdapter da = new SqlDataAdapter(command); // The rest of your code here... } } 

我想指出的一些事情:

  1. 用户名通常不区分大小写,因此查询应该使用LIKE或UCASE()比较来查找用户名。
  2. 从查询中可以明显看出,您的密码没有经过哈希处理或加密。 这真是太糟了。 阅读散列密码。 https://crackstation.net/hashing-security.htm
  3. 基本上你在这里创建的东西叫做对象关系管理器。 除非你特别感兴趣学习如何开发一个,我强烈建议你使用经过试验和测试的。 我个人使用nHibernate。 Hibernate是作为Java的ORM编写的,而nHibernate在.Net应用程序中非常流行。 entity framework是微软的ORM。 我不认为它与nHibernate相当,但它不断改进。