1

I'm using Dapper to work with sql database. I have some search logic in my website project.

My search gets list of string parameters.

//filter is list of strings

var sql = new StringBuilder();
sql.Append("SELECT LibraryDocumentId FROM LibraryDocumentKeywords WHERE ");

sql.Append(string.Join("OR ", filter.Select(f => string.Format("LOWER(Keyword) LIKE '%{0}%'", f)).ToList()));

var isList = conn.Query<int>(sql.ToString()).ToList();

Actually I don't want to use this approach of generating dynamic SQL query, because Dapper will cache every single query. I would prefer to pass filter with parameter. Can someone help me with that? Any idea ?

Mike
  • 3,766
  • 3
  • 18
  • 32
  • Have you read this related question? http://stackoverflow.com/questions/9481678/how-to-create-arguments-for-a-dapper-query-dynamically?rq=1 – Turophile May 15 '14 at 14:25

1 Answers1

8

What you have at the moment is also a huge SQL injection risk. You might want to use DynamicParameters here, i.e. (completely untested, you may need to tweak slightly):

var sql = new StringBuilder(
    "SELECT LibraryDocumentId FROM LibraryDocumentKeywords");
int i = 0;
var args = new DynamicParameters();
foreach(var f in filter) {
    sql.Append(i == 0 ? " WHERE " : " OR ")
        .Append("LOWER(Keyword) LIKE @p").Append(i);
    args.Add("p" + i, "%" + f + "%");
    i++;
}
var data = conn.Query<int>(sql.ToString(), args);

This should cache fairly cleanly (one cache item per number of filters, regardless of their contents).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900