此代码有太多问题。
- 表,列和条件作为字符串传递并连接,这意味着代码很容易进行SQL注入。
- 像表,列标准这样的数据库细节被分散到函数的调用者中。你打算使用这种方法来查询Visitor表以外的任何东西吗?
- 当只需要单个值时使用阅读器。
- 的连接的
using
块之外创建并存储在一个字段。 这是definitelly内存泄漏,也可能是连接泄漏。只需在本地创建连接。
一个简单的命令调用修复所有这些问题:
public int CheckIDVisitor(visitorName)
{
string query = "SELECT ID FROM Visitors where [email protected]";
using (var sqlConn=new SqlConnection(Properties.Default.MyDbConnectionString))
using(var cmd=new SqlCommand(query,sqlConn))
{
var cmdParam=cmd.Parameters.Add("@name",SqlDbType.NVarChar,20);
cmdParam.Value=visitorName;
sqlConn.Open();
var result=(int?)cmd.ExecuteScalar();
return result??0;
}
}
你也可以事先创建的命令,并将其存储在一个领域。
public void InitVisitorCommand()
{
string query = "SELECT ID FROM Visitors where [email protected]";
var cmd=new SqlCommand(query,sqlConn);
var cmdParam=cmd.Parameters.Add("@name",SqlDbType.NVarChar,20);
_myVisitorCommand=cmd;
}
...
public int CheckIDVisitor(visitorName)
{
using (var sqlConn=new SqlConnection(Properties.Default.MyDbConnectionString))
{
_myVisitorCommand.Parameters.["@name"]Value=visitorName;
_myVisitorCommand.Connection=sqlConn;
sqlConn.Open();
var result=(int?)cmd.ExecuteScalar();
return result??0;
}
}
一个更好的办法是使用微型ORM像Dapper.Net摆脱所有这些代码:
public int CheckIDVisitor(visitorName)
{
using (var sqlConn=new SqlConnection(Properties.Default.MyDbConnectionString))
{
string sql = "SELECT ID FROM Visitors WHERE [email protected]"
var result = conn.Query<int?>(sql, new { name = visitorName);
return result??0;
}
}
你可以要执行它每次连接到命令的连接
或者
public int[] CheckIDVisitors(string []visitors)
{
using (var sqlConn=new SqlConnection(Properties.Default.MyDbConnectionString))
{
string sql = "SELECT ID FROM Visitors WHERE name IN @names"
var results = conn.Query<int?>(sql, new { names = visitors);
return results.ToArray();
}
}
从这里开始:http://stackoverflow.com/questions/332365/how-does-the-sql-injection-from-the-bobby-tables-xkcd-comic-work – Steve
此代码有很多的错误,并不会甚至运行(你忘了打开连接)。它也暗示连接泄漏 - 'sqlcon'没有被定义,这意味着它是一个没有被清除的字段。它可能不会在其他方法中正常关闭。 –
@Steve谢谢你的链接,这非常有帮助。 –