小巧玲珑

时间:2012-02-18 21:42:09

标签: sql-order-by dapper

使用dapper时,有没有理由不能以正确的顺序检索以下代码?

connection.Query<User>("SELECT id, name " +
                       "FROM user " +
                       "ORDER BY @sort @dir " +
                       "LIMIT @offset, @pageSize; ",
                       new {
                           sort = sortOrder, // sortOrder = "name"
                           dir = sortDirection, // sortDirection = "ASC"
                           offset = pageIndex * pageSize, // offset = 0
                           pageSize = pageSize // pageSize = 10
                       });

它总是在不应用订单的情况下返回。

我可以将sortOrder和sortDirection直接放入字符串中,就像这样

"SELECT id, name " +
"FROM user " +
"ORDER BY " + sortOrder + " " + sortDirection + " " +
"LIMIT @offset, @pageSize; "

但是我不确定这会如何影响dapper,因为我相信它有自己的查询计划缓存

另外,有没有办法查看dapper生成的查询?

2 个答案:

答案 0 :(得分:7)

当然,通常数据库引擎不允许您参数化列名。例如:

var row = cnn.Query("select @bob as col from table", new {bob = "col"}).first(); 
// most likely returns "row.col == col"

当您尝试按顺序对参数化进行参数化时,我建议您使用内联替换,前提是您可以保证您的转义,bobby表总是潜伏着。 (或者你可以使用proc)

我不确定(MySQL?Oracle?)的分析器周围的情况,但您可以使用MiniProfiler之类的工具来查看SQL。

它会影响缓存,但sortOrder和sortDirection只有少量排列,因此影响很小。

答案 1 :(得分:0)

您可以只在您的订单中使用case语句。只要您只处理几列,就不会太疯狂。

public List<Signup> GetNext(int Id, int RowsToFetch, string SortedBy)
        {

            string _sortedBy = SortedBy.Trim();
            using (IDbConnection conn = Connection)
            {
                string sQuery = @"SELECT TOP(@ROWSTOFETCH)
                                    [Id]
                                   ,[FirstName]
                                   ,[LastName]
                                   ,[EmailAddress]
                                  FROM [dbo].[vwBaseQuery]
                                  WHERE ID >= @ID
                                  ORDER BY 
                                          CASE WHEN @SORTEDBY = 'Id ASC' THEN Id END ASC,
                                          CASE WHEN @SORTEDBY = 'Id DESC' THEN Id END DESC,
                                          CASE WHEN @SORTEDBY = 'FirstName ASC' THEN FirstName END ASC,
                                          CASE WHEN @SORTEDBY = 'FirstName DESC' THEN FirstName END DESC,
                                          CASE WHEN @SORTEDBY = 'LastName ASC' THEN LastName END ASC,
                                          CASE WHEN @SORTEDBY = 'LastName DESC' THEN LastName END DESC,
                                          CASE WHEN @SORTEDBY = 'EmailAddress ASC' THEN EmailAddress END ASC,
                                          CASE WHEN @SORTEDBY = 'EmailAddress DESC' THEN EmailAddress END DESC";
                conn.Open();

                var result = conn.Query<Signup>(sQuery, new {
                    SORTEDBY = _sortedBy,
                    ROWSTOFETCH = RowsToFetch,
                    ID = Id
                }).ToList();
                return result;
            }
        }