ich hab eine API, die auf eine SQL Datenbank zugreift. Insgesamt sind es grob 300 verschiedenste Abfragen.
Lange Abfragen, die im Code schwer zu lesen sind, habe ich als StoredProcedur angelegt, kürzere Abfragen direkt im Code.
Beim Refactoring ist mir dieses Durcheinander aufgefallen un dich überlege, ob es nicht bessere Lösungen gibt?!
Beispielsweise könnte man ja die Strings auch in eine separate TXT ablegen und abrufen, oder eine statische Klasse nutzen...
Also ich habe dazu eine eigene Klasse - im Code ist nur der Befehl zum Nachladen der Befehle fest hinterlegt. Alle anderen Befehle liegen in der Datenbank und werden entweder beim Start oder bei Bedarf nachgeladen.
Also ich habe auch schon oft darüber nachgedacht wie ich das bei meinen Service machen sollte. Die Idee die Sql Queries in einer txt/sql/json Datei zu hinterlegen hatte ich auch schon. Bin aber letztlich zu dem Schluss gekommen, dass das keine gute Idee ist und zwar aus dem ganz einfachen Grund, das jemand die Datei manipulieren könnte. Die Queries in der Datenbank zu speichern halte aus den selben Grund auch für eine schlechte Idee.
Ich schreibe keinen SQL Code mehr, sondern lasse das vom ORM machen. So ist alles aufgeräumt, typsicher und selbstdokumentierend.
Weiterentwicklung und Fehlersuche ist auch viel einfacher.
Alt : if (such_ar_bez1 != "") sqlstr += "ar_bez1 LIKE '" + such_ar_bez1.ToSqlString() + "' AND ";
Neu : if (such_ar_bez1 != "") qry = qry.ar_bez1().IsLike(such_ar_bez1).And();
Das ist jetzt ein eigenes ORM, jetzt würde ich aber Dapper oder EF benutzen.
Das ist jetzt ein eigenes ORM, jetzt würde ich aber Dapper oder EF benutzen.
Wobei Dapper aber das SQL schreiben nicht ab nimmt - zumindest nach meinem letzten Stand.
Es mappt nur die Ergebnisse passend zu den eigenen Klassen.
Das übernehmen nur die "großen ORMs" wie EF oder nHibernate, sind dadurch aber auch deutlich komplexer.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Palladin007 am .
Wenn es Request Queries sind: alles über EF Core (selten Dapper), sehr viel über entsprechend indizierte Queries.
Wenn es Round Trip Queries sind: über Stored Procs (über EFCore Connection), sofern es MSSQL ist.
Genau über den Weg ist auch das Forum hier umgesetzt; universell einsetzbar.
Das habe ich ungefähr im Jahr 2004 geschrieben, da gab es den guten Artikel noch nicht.
In der Extension 'ToSqlString()' habe ich zwar versucht alles rauszufiltern was zu Fehlern oder Missbrauch führen kann, hat aber nicht immer funktioniert.
Also da passiert schon deutlich mehr als nur Zeichen rausfiltern/escapen.... SqlCommand Source Code
Da wird völlig Typ-gerecht ein vollständiges Cleanup und Aufbau des SQL Befehls vorgenommen.
Ich meinte konkret den Code zur Umwandlung der Parameter bei der Erzeugung des SQL-Befehls. Dort werden dann u.a. diese Hilfsmethoden aus SqlServerEscapeHelper verwendet:
/// <summary>
/// Escape a string to be used inside TSQL literal, such as N'somename' or 'somename'
/// </summary>
static internal string EscapeStringAsLiteral(string input) {
Debug.Assert(input != null, "input string cannot be null");
return input.Replace("'", "''");
}
/// <summary>
/// Escape a string as a TSQL literal, wrapping it around with single quotes.
/// Use this method to escape input strings to prevent SQL injection
/// and to get correct behavior for embedded quotes.
/// </summary>
/// <param name="input">unescaped string</param>
/// <returns>escaped and quoted literal string</returns>
static internal string MakeStringLiteral(string input) {
if (ADP.IsEmpty(input)) {
return "''";
}
else {
return "'" + EscapeStringAsLiteral(input) + "'";
}
}
Ähnlich sieht es dann bei den anderen Datenbanken (Oracle, PostGres, ...) aus.
Datenbanken nehmen ja (leider) nur direkt SQL-Strings entgegen, d.h. diese müssen vom Client aus zusammengesetzt werden (auch wenn vom Anwender Parameter verwendet werden).
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am .