如何根据条件在tSQL中动态添加SELECT语句中的列?

时间:2018-03-13 21:23:44

标签: c# entity-framework tsql

我正在使用tSql创建parameters,并根据某些条件我想在SELECT语句中添加列,我不知道该怎么做。

我的逻辑:

var keywordClause = keyword.IsNotEmpty()
                    ? "[Name] like '%" + keyword + "%'"
                    : "1 = 1";
// keywordClause  = "[Name] like '%Test%'"

var orderBy = sortParameters.ToOrderBy();
// orderBy =  "Name ASC"

var parameters = new List<SqlParameter>
{
    new SqlParameter("@Keyword", keywordClause),
    new SqlParameter("@OrderBy", orderBy)
};

var sql = string.Format(@"SELECT Id,
                                 Name,
                                 CreateDateTime Created
                          FROM CallCenter WITH (NOLOCK)
                          WHERE(IsDeleted = 0)
                          AND @Keyword 
                          ORDER BY @OrderBy");

return _PageList(ctx => ctx.CallCenterSummaries.SqlQuery(sql, parameters.ToArray())
                .AsQueryable()
                .Select(d => d.TrimSpaces()), page, pageSize);

根据我的逻辑,我期待这个查询:

SELECT Id,
       Name,
       CreateDateTime Created
FROM CallCenter WITH (NOLOCK)
WHERE(IsDeleted = 0)
AND [Name] like '%Test%'
ORDER BY Name ASC;

此处我收到"An expression of non-boolean type specified in a context where a condition is expected, near 'ORDER'."个异常,我相信它会将Name作为字符串。我怎样才能得到理想的结果?

1 个答案:

答案 0 :(得分:1)

您不能将SqlParameter作为整个条款 - 它必须是条款的右侧。对于您的场景 - 以下内容应该有效。

var parameters = new List<SqlParameter>
{
    new SqlParameter("@Keyword", keyword.IsNotEmpty() ? keyword : "%")
};

var sql = string.Format($@"SELECT Id,
                                 Name,
                                 CreateDateTime Created
                          FROM CallCenter WITH (NOLOCK)
                          WHERE(IsDeleted = 0)
                          AND [Name] like @Keyword 
                          ORDER BY {orderBy}");

修改 我编辑了我的代码示例,使用order by作为插值字符串中的值而不是SqlParameter,但是,如果{{1}的值,这会打开你的Sql注入}受用户输入的影响。

或者,我建议您不要在查询中使用orderBy子句,并在将结果传回内存之前对其进行排序。