Gibt es eine Möglichkeit, parametrisierte SQL für verschiedene Anbieter zu schreiben?
Beispiel:
connection.QuerySingle<string>("select name from user where id = :id", new {id = 4});
Dies würde mit einem Oracle-Provider funktionieren, aber MsSql benötigt "@id" als Parameter.
Die Dapper FAQ sagt:
Es ist Ihre Aufgabe, das SQL mit Ihrem Datenbankanbieter kompatibel zu schreiben.
Aber wie? Derzeit haben wir die folgende Problemumgehung:
$".. where id = {db.ParamToken}id"
Aber das ist wirklich hässlich in größeren SQL zu schreiben.
Gibt es eine Möglichkeit, ein Token für alle Anbieter zu haben?
"Gibt es eine Möglichkeit, ein Token für alle Anbieter zu haben?"
Ja, aber es erfordert etwas Setup. Sie können nützliche datenbankproviderspezifische Informationen von einer vorhandenen DBConnection
. Rufen Sie zuerst die DataSourceInformation- Tabelle aus der Verbindung ab:
DbConnection connection = GetSomeConnection();
var infoTable = connection.GetSchema(DbMetaDataCollectionNames.DataSourceInformation);
Diese Tabelle wird eine Zeile mit verschiedenen Provider-Informationen enthalten. In Bezug auf die Parameterbenennung gibt es eine Spalte namens ParameterMarkerPattern
die eine Regex
Musterzeichenfolge zum Überprüfen des Parameters darstellt. Wenn diese Spalte Daten enthält, ist das erste Zeichen Ihr DbParameter
Marker. Wenn die Spalte leer ist, kann das ParameterMarkerFormat
ein Zeichenfolgenformat angeben, das beim ParameterMarkerFormat
des ParameterMarkerFormat
angewendet wird.
"Aber das ist wirklich hässlich, um in größeren SQL zu schreiben".
Das geht nicht wirklich um, wenn Sie überlegen, Ihre SQL direkt zu formatieren, und Ihre Problemumgehung ist schon viel einfacher als diese. Die zusätzlichen Daten, die Sie von der DataSourceInformation
sollten jedoch ausreichend sein, um Ihre eigene Zeichenfolge an eine Methode Ihrer Erstellung zu übergeben, die ein Standardparameterstartzeichen (wie @
) durch das richtige vom Provider ersetzen würde:
string sql = SqlIfy("SELECT name FROM user WHERE id = @id");
Sie können damit noch weiter gehen und dasselbe für zitierte Bezeichner tun. Sie können etwas eingeben wie:
"SELECT [Name] FROM [dbo].[SomeTable]"
und habe es wie herauskommen
SELECT "Name" FROM "dbo"."SomeTable"
Alles abhängig vom Anbieter. Wenn Sie Abfragen für eine benutzerdefinierte Basisanbie- terklasse dynamisch erstellen möchten, können Sie eine erste Verbindung öffnen und alle anbieterspezifischen Daten speichern. Sie möchten DbConnection.GetSchema
jedes Mal aufrufen, DbConnection.GetSchema
Sie eine Verbindung verwenden.
Es ist Ihre Aufgabe, das SQL mit Ihrem Datenbankanbieter kompatibel zu schreiben.
Das ist richtig. Dapper generiert keine SQL-Abfragen für Sie. Während Sie Abfragen schreiben, ist es Ihre Aufgabe, eine Abfrage über verschiedene Anbieter hinweg zu schreiben.
Wie machst du das? Zu viele Möglichkeiten. Warum sieht dein Workaround schlecht für dich aus? Es ist eine großartige Lösung. Setzen Sie das Provider-Token irgendwo und setzen Sie es so, wie Sie es gerade tun:
"select name from user where id = " + db.ParamToken + "id"
Dies kann für Sie hässlich aussehen, weil Sie dies (und viele ähnliche andere Hacks) überall in Ihrem Code an vielen Stellen tun müssen.
Bessere Lösung ist es