Ähnlich wie Spaltennummer anstelle von Spaltenname, aber ich glaube, dass es anders ist, weil das für unbenannte Spalten war, während meine Spalten benannt sind, ich kenne nur die Namen im Voraus nicht.
Zuerst etwas Hintergrund. Ich erstelle eine Methode, die eine Abfrage und ihre Argumente als Parameter akzeptiert, dann die Abfrage ausführt (mit Dapper) und überprüft, ob die erste Zeile, die erste Spalte eine 1 oder 0 ist. Sie soll als generischer Validator funktionieren Datenbanken.
Der Benutzer könnte z. B. eine Abfrage eingeben, die in der einzigen Spalte der einzigen Zeile eine 1 zurückgibt, wenn in einer Tabelle ein Wert vorhanden ist, andernfalls eine 0. Die Verwendung dieser Methode ist absichtlich sehr breit und der größte Teil des Aufwands wird auf den Benutzer geschrieben, der die Abfrage schreibt (ich sollte auch klarstellen, dass der "Benutzer" in diesem Fall immer ein anderer Entwickler ist und die Verwendung in Code erfolgt, der diese Methode aufruft). nicht, sagen wir, Formeingabe).
Ich möchte meine Datenbank abfragen und den Wert der ersten Zeile, erste Spalte abrufen, ohne vorher den Namen der Spalte zu kennen. Im Idealfall (obwohl ich mir nicht sicher bin, ob das im Dapper-Call möglich ist oder nicht), möchte ich auch verlangen, dass im Ergebnis nur eine Zeile und eine Spalte stehen. Als ich mich umschaute, basierte ich meine erste Lösung auf der ersten Antwort dieses Posts, fand aber, dass ich dafür den Namen der Spalte kennen musste:
var dict = connection.Query(query, parameters).ToDictionary(row => (string)row.VALUE);
if(dict.ElementAt(0).Value != 1){
//do stuff
}
Ich dachte daran, nur eine Anforderung hinzuzufügen, dass der Benutzer einen Alias hinzufügt, der der ersten Spalte einen konstanten Wert (in diesem Fall VALUE
) gibt, aber ich würde es vorziehen, meinen Benutzer möglichst wenig zu belasten.
Letztendlich ist mein Kernproblem: Wie kann ich den Wert einer benannten Spalte in einem DB mit Dapper abrufen, ohne den Namen der Spalte zu kennen? Hat jemand irgendwelche Ideen?
Ich habe dies erfolgreich getan, indem ich einfach int als Typ in der generischen Abfrage-Methode verwendet habe:
int value = conn.Query<int>(sql,
commandType: CommandType.StoredProcedure).FirstOrDefault();
Beachten Sie die Verwendung der FirstOrDefault-Methode. Sie erhalten also 0 oder was auch immer der Wert von der DB ist.
Tortuga-Kette benutzen
var result = DataSource.Sql(query, parameters).ToInt32().Execute();
Ich möchte auch verlangen, dass nur eine Zeile und eine Spalte im Ergebnis stehen
Standardmäßig verwendet Chain DbCommand.ExecuteScalar. Dies gibt die erste Spalte der ersten Zeile zurück und ignoriert alles andere. Um diese Einschränkung hinzuzufügen, würde ich Folgendes tun:
var result = DataSource.Sql(query, parameters).ToInt32List().Execute().Single;
Eine weitere Möglichkeit besteht darin, zu ändern, wie Sie das SQL generieren. Beispielsweise,
var filterObject = new {ColumnA = 1, ColumnB = "X", ColumnC = 17};
var result = DataSource.From(tableName, filterObject).ToInt32(columnName).Execute();
Dies hat den Vorteil, immun gegen SQL-Injection-Angriffe zu sein (was wahrscheinlich ein Problem für Sie ist) und stellt sicher, dass SQL nur eine Spalte zurückgibt, bevor es ausgeführt wird.