参数化
使用参数化可以有效防止 SQL
注入。在 Fireasy 里统一使用 ParameterCollection
类,所有的查询和执行方法都支持参数化。如下所示:
[TestMethod]
public void TestQueryByParameters()
{
var parameters = new ParameterCollection();
parameters.Add("productid", 1);
var sql = (SqlCommand)"select productid, productname from products where productid = @productid";
using (var db = DatabaseFactory.CreateDatabase())
{
foreach (var item in db.ExecuteEnumerable<Products>(sql, null, parameters))
{
Console.WriteLine(item.ProductName);
}
}
}
SQL
里统一使用参数前缀 @,不用区分不同的数据库,Fireasy 会自动进行转换 见 SQL 语法服务 -- 参数前缀 。ParameterCollection
类的 Add 方法也不需要使用参数前缀。
参数分为输入型、输出型和输入转出型,分别用 Add、AddOut 和 AddInOut 方法添加到集合中。下面的示例演示如何执行存储过程并返回结果:
[TestMethod]
public void TestReturnParameter()
{
var parameters = new ParameterCollection();
parameters.Add("name", "admin");
parameters.Add("type", 1);
parameters.Add("password", "123");
parameters.AddOut<string>("ret", 100);
using (var database = DatabaseFactory.CreateDatabase())
{
database.ExecuteNonQuery((ProcedureCommand)"sp_check_login", parameters);
Assert.AreEqual("succeed", parameters["ret"].Value);
}
}
存储过程 sp_check_login 的定义如下(MySql):
CREATE PROCEDURE sp_check_login(name varchar(50), type int, password varchar(50), out ret varchar(100))
BEGIN
if name = 'admin' and password = '123' then
set ret = 'succeed';
else
set ret = 'failed';
end if;
END
这里也支持数组类型的参数,应用于 IN
表达式中。如下所示:
[TestMethod]
public void TestQueryByArrayParameter()
{
var parameters = new ParameterCollection();
parameters.Add("productid", new int [] { 1, 2, 3, 4 });
var sql = (SqlCommand)"select productid, productname from products where productid in (@productid)";
using (var db = DatabaseFactory.CreateDatabase())
{
foreach (var item in db.ExecuteEnumerable<Products>(sql, null, parameters))
{
Console.WriteLine(item.ProductName);
}
}
}
💡 多说一句
ParameterCollection
类支持从字典或其他类型进行构造或强制转换,以及相加和相减等。如下所示:
public void TestNewParameters()
{
var dict = new Dictionary<string, object> { { "Name", "fireasy" }, { "Age", 1 } };
var pc1 = new ParameterCollection(new { Address = "kunming", AreaCode = "5301" });
var pc2 = new ParameterCollection(dict);
var pc3 = (ParameterCollection)dict;
var pc4 = pc1 + pc2;
}