参数化


  使用参数化可以有效防止 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;
}