Dapper Order By - PullRequest
       8

Dapper Order By

5 голосов
/ 19 февраля 2012

Есть ли причина, по которой следующий код не будет получен в правильном порядке при использовании 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?

Ответы [ 2 ]

7 голосов
/ 20 февраля 2012

Конечно, в общем случае движки баз данных не позволяют параметризировать имена столбцов. Так, например:

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

Когда вы пытаетесь параметризовать порядок по пунктам, я бы порекомендовал использовать встроенную подстановку, при условии, что вы можете гарантировать, что ваши экранирующие таблицы всегда будут скрыты. (Либо так, либо вы можете использовать процедуру)

Я не уверен насчет ситуации с профилировщиками для (MySQL? Oracle?), Но вы могли бы использовать инструмент типа MiniProfiler , чтобы увидеть SQL.

Это повлияет на кеширование, однако существует лишь небольшое количество перестановок sortOrder и sortDirection, поэтому влияние будет минимальным.

0 голосов
/ 26 марта 2019

Вы можете просто использовать регистрацию в вашем заказе. Пока вы имеете дело только с несколькими столбцами, это не станет слишком сумасшедшим.

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;
            }
        }
...