Existe-t-il un moyen d’écrire des sql paramétrés pour différents fournisseurs?
Exemple:
connection.QuerySingle<string>("select name from user where id = :id", new {id = 4});
Cela fonctionnerait avec un fournisseur oracle mais MsSql nécessite "@id" comme paramètre.
La FAQ de Dapper dit:
Il vous incombe d'écrire le code SQL compatible avec votre fournisseur de base de données.
Mais comment? Actuellement, nous avons la solution de contournement suivante:
$".. where id = {db.ParamToken}id"
Mais c’est vraiment moche d’écrire dans des fichiers SQL plus volumineux.
Y a-t-il un moyen d'avoir un jeton pour tous les fournisseurs?
"Y a-t-il un moyen d'avoir un jeton pour tous les fournisseurs?"
Oui, mais cela nécessite une configuration. Vous pouvez récupérer des informations spécifiques au fournisseur de base de données à partir d'une DBConnection
existante. Récupérez d'abord la table DataSourceInformation à partir de la connexion:
DbConnection connection = GetSomeConnection();
var infoTable = connection.GetSchema(DbMetaDataCollectionNames.DataSourceInformation);
Cette table aura une seule ligne avec diverses informations sur le fournisseur. En ce qui concerne le nommage des paramètres, il y aura une colonne nommée ParameterMarkerPattern
qui représente une chaîne de modèle Regex
pour valider le paramètre. Si cette colonne contient des données, le premier caractère sera votre marqueur DbParameter
. Si la colonne est vide, le ParameterMarkerFormat
peut vous donner un format de chaîne à appliquer lors de la création du nom de votre paramètre.
"Mais c’est vraiment moche d’écrire dans des SQL plus grands".
Cela ne résout pas vraiment le problème si vous envisagez de formater directement votre SQL, et que votre solution est déjà beaucoup plus simple. Cependant, les données supplémentaires fournies par DataSourceInformation
devraient vous permettre de transmettre votre propre chaîne à une méthode de votre création, qui remplacerait un caractère de démarrage de paramètre par défaut (comme @
) par le caractère approprié du fournisseur:
string sql = SqlIfy("SELECT name FROM user WHERE id = @id");
Vous pouvez aller encore plus loin avec ceci et faire la même chose pour les identifiants cités. Vous pouvez passer quelque chose comme:
"SELECT [Name] FROM [dbo].[SomeTable]"
et le faire sortir comme
SELECT "Name" FROM "dbo"."SomeTable"
Tout dépend du fournisseur. Si vous souhaitez créer dynamiquement des requêtes sur une classe de fournisseur de base personnalisée, vous pouvez ouvrir une connexion initiale et stocker toutes les données spécifiques au fournisseur. Vous ne voudriez pas appeler DbConnection.GetSchema
chaque fois que vous utilisez une connexion.
Il vous incombe d'écrire le code SQL compatible avec votre fournisseur de base de données.
C'est correct Dapper ne génère pas de requêtes SQL pour vous. Lorsque vous écrivez des requêtes, vous devez écrire une requête inter-fournisseur.
Comment tu fais ça? Trop de façons. Pourquoi votre solution de contournement vous semble-t-elle mauvaise? C'est une excellente solution. Définissez le jeton de fournisseur quelque part et définissez-le comme vous le faites maintenant:
"select name from user where id = " + db.ParamToken + "id"
Cela peut sembler moche pour vous parce que vous devez le faire (et beaucoup d'autres hacks similaires) partout dans votre code à de nombreux endroits.
Une meilleure solution est de