问题
Is there any reason why the following code wouldn't be retrieved in the correct order when using 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
});
It always returns without applying the ordering.
I could just place the sortOrder and sortDirection directly into the string like this
"SELECT id, name " +
"FROM user " +
"ORDER BY " + sortOrder + " " + sortDirection + " " +
"LIMIT @offset, @pageSize; "
but I'm not sure how that will effect dapper since I believe it has it's own query plan caching.
Also, is there a way to view the query that is generated by dapper?
回答1:
Sure, in general database engines do not allow you to parametrize column names. So for example:
var row = cnn.Query("select @bob as col from table", new {bob = "col"}).first();
// most likely returns "row.col == col"
When you are trying to parametrize order by clauses I would recommend using inline substitution, provided you can guarantee your escaping, bobby tables is always lurking. (Either that or you could use a proc)
I am not sure about the situation around profilers for (MySQL? Oracle?) but you could use a tool like MiniProfiler to see the SQL.
It will affect caching, however there are only a small number of permutations of sortOrder and sortDirection so the impact is minimal.
回答2:
You can just use a case statement in your order by. As long as you're only dealing with a few columns, it won't get too crazy.
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;
}
}
来源:https://stackoverflow.com/questions/9344340/dapper-order-by