使用ObjectContext.ExecuteStoreQuery <t>()</t>在SQL查询中参数化“ORDER BY”

时间:2014-12-29 03:47:03

标签: c# asp.net entity-framework-4

我的问题是在这个问题之上:

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   变量作为标识列位置的表达式的一部分。   只有在通过表达式引用进行排序时,才允许使用变量   列名。

2 个答案:

答案 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);