Je suis nouveau dans Dapper et j'écris une requête qui tirera d'un schéma et d'une table fournis, ainsi que de l'ordre et du filtrage dynamiques. Dapper rendre les paramètres dynamiques très simple, cependant, je ne suis pas sûr de savoir comment faire cela avec des tables dans les clauses order by et where. Voici ma méthode ci-dessous, et je vois les problèmes avec injection SQL:Comment désinfecter un nom de table dynamique à l'aide de Dapper?
public GridData GetGridData(string schema, string table, TableDataParameters tableDataParameters)
{
using (var dbConnection = VarConnection)
{
dbConnection.Open();
if (!this.TableExists(dbConnection, schema, table))
{
throw new ItemNotFoundException($"Could not locate table {schema}.{table}.");
}
string orderyByClause = string.Join(",", tableDataParameters.SortModel.Select(s => $"[{s.ColId}] {(s.Sort.ToLower() == "asc" ? "asc" : "desc")}"));
var parameters = new DynamicParameters();
string whereClause;
if (tableDataParameters.FilterModel == null || !tableDataParameters.FilterModel.Any())
{
whereClause = "1=1";
}
else
{
whereClause = string.Join(" AND ", tableDataParameters.FilterModel.Select((fm, i) =>
{
string whereParam = $"whereParam{i}";
parameters.Add(whereParam, fm.Filter);
if (fm.Operation == "startsWith")
{
return $"[{fm.Column}] LIKE @{whereParam} + '%'";
}
throw new InvalidOperationException($"Unsupported filter operation '{fm.Operation}'");
}));
}
var query = $"SELECT COUNT(1) [total] " +
$"FROM [{schema}].[{table}] " +
$"WHERE {whereClause} " +
$"SELECT * " +
$"FROM [{schema}].[{table}] " +
$"WHERE {whereClause} " +
$"ORDER BY {orderyByClause} " +
$"OFFSET {tableDataParameters.StartIndex.Value} ROWS " +
$"FETCH NEXT {tableDataParameters.StopIndex.Value - tableDataParameters.StartIndex.Value} ROWS ONLY";
int total = 0;
using (var reader = dbConnection.ExecuteReader(query, parameters))
{
// First batch, it's the count
if (reader.Read())
{
total = reader.GetInt32(0);
}
var gridColumns = new List<GridColumn>();
var gridRows = new List<string[]>();
if (reader.NextResult() && reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
string key = reader.GetName(i);
gridColumns.Add(new GridColumn(key, key, null, ""));
}
var items = new object[reader.FieldCount];
reader.GetValues(items);
gridRows.Add(items.Select(i => i.ToString()).ToArray());
}
while (reader.Read())
{
var items = new object[reader.FieldCount];
reader.GetValues(items);
gridRows.Add(items.Select(i => i.ToString()).ToArray());
}
return new GridData(tableDataParameters.StartIndex.Value, tableDataParameters.StopIndex.Value, total, gridRows.Count(), gridColumns.ToArray(), gridRows.ToArray());
}
}
}
Dois-je utiliser quelque chose comme DbCommandBuilder.QuoteIdentifier, https://msdn.microsoft.com/en-us/library/system.data.common.dbcommandbuilder.quoteidentifier(v=vs.110).aspx dans ce cas? Cela ne semble pas aider autant ici.
Merci!
J'ai fini par utiliser une liste blanche. – TheTFo