2017-06-01 2 views
0

Ich bin neu in Dapper, und schreibe eine Abfrage, die aus einem bereitgestellten Schema und Tabelle zusammen mit dynamischen Sortierung und Filterung ziehen wird.Wie kann ich einen dynamischen Tabellennamen mithilfe von Dapper bereinigen?

Dapper machen dynamische Parameter sehr einfach, aber ich bin mir nicht sicher, wie dies mit Tabellen in der Reihenfolge von und Where-Klauseln zu tun. Hier ist meine Methode unten, und ich sehe die Probleme mit SQL-Injection:

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()); 
      } 
     } 
    } 

Soll ich so etwas wie DbCommandBuilder.QuoteIdentifier, https://msdn.microsoft.com/en-us/library/system.data.common.dbcommandbuilder.quoteidentifier(v=vs.110).aspx in diesem Fall? Das scheint nicht so viel hier zu helfen.

Danke!

+0

Ich landete nur mit einer weißen Liste. – TheTFo

Antwort

1

Dynamische Parameter ist ein Oxymoron! Dapper macht Parameter einfach, aber Sie können Tabellen- und Spaltennamen nicht parameterisieren. Dies ist eine Einschränkung von SQL, nicht Dapper. Wenn Sie dies wirklich tun wollen, müssen Sie dynamische SQL- und String-Methoden verwenden, und Sie sind in Bezug auf SQL-Injection auf sich gestellt.

Sie werden glücklicher sein und länger leben, wenn Sie dies nicht tun. Es ist nur eine schlechte Straße. Sie fügen nicht viel Wert hinzu, und Sie führen potenziell eine Menge Probleme und Einschränkungen ein.

Es sieht so aus, als ob Sie eine App schreiben, um eine Datenbank zu durchsuchen. Dafür gibt es bereits gute Werkzeuge!

Verwandte Themen