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).