我的问题是在这个问题之上:
Entity Framework and the raw string query - SQL injection prevention
如何在此上下文中通过命令参数化限制和顺序?
非常感谢。
更新:
我尝试了这段代码,但它不起作用:
var filters = new StringBuilder();
var parameters = new List<object>();
decimal numRealPrice = 25.00m;
filters.Append("RealPrice = @RealPrice");
var paramRealPrice = new SqlParameter("@RealPrice", SqlDbType.Decimal);
paramRealPrice.Value = numRealPrice;
parameters.Add(paramRealPrice);
var paramSort = new SqlParameter("@field", SqlDbType.NVarChar);
paramSort.Value = "Id";
parameters.Add(paramSort);
string sqlStatement = "SELECT * FROM gift WHERE ";
sqlStatement = sqlStatement + filters + " ORDER BY @field DESC";
生成的SQL是:
exec sp_executesql N'SELECT * FROM gift WHERE RealPrice = @RealPrice ORDER BY @Id DESC',
N'@RealPrice decimal(4,2), @Id varchar(2)',
@RealPrice=25.00,
@Id='id'
go
错误信息是:
ORDER BY编号1标识的SELECT项包含a 变量作为标识列位置的表达式的一部分。 只有在通过表达式引用进行排序时,才允许使用变量 列名。
答案 0 :(得分:1)
您无法参数化ORDER BY
子句。由于您已经在C#中构建/编写查询,因此最有效的方法是简单地将该参数列入白名单并直接添加该子句:
string orderByField = "Id"; // or whatever
// whitelist the field
switch(orderByField) {
case "Id":
case "Name":
...
break; // these are OK
default:
throw new InvalidOperationException("Illegal order clause: " + orderByField);
}
sqlStatement = sqlStatement + filters + " ORDER BY " + orderByField + " DESC";
答案 1 :(得分:0)
与它在该问题的答案中显示的方式完全相同但是您需要更改SQL以在其中为OrderBy子句创建一个case语句。
SELECT * FROM gift
ORDER BY
CASE @dir
WHEN 'desc' THEN
CASE @col
WHEN 'id' THEN id
END
END
DESC,
CASE @dir
WHEN 'asc' THEN
CASE @field
WHEN 'id' THEN id
END
END
然后将参数插入
var param = new SqlParameter("@field", SqlDbType.NVarChar);
param.Value = name;
parameters.Add(param);
然后在这里另一个确定方向
var param = new SqlParameter("@dir", SqlDbType.NVarChar);
param.Value = 'desc'; // or 'asc'
parameters.Add(param);