Utiliser Dapper avec Oracle

c# dapper oracle

Question

Nous utilisons Oracle comme fournisseur de base de données et avons cherché à remplacer une partie de notre couche d'accès aux données (difficile à maintenir, plus difficile à fusionner) avec un modèle basé sur un référentiel plus sûr, utilisant Dapper dans la couche inférieure. Cependant, nous avons rencontré un certain nombre de problèmes lors de son utilisation avec Oracle.

  • Paramètres nommés: ceux-ci semblent être ignorés, chaque fois qu'ils sont utilisés dans une requête Oracle semble les interpréter dans n'importe quel ordre. Le SqlMapper renvoie des paramètres correctement nommés, ils ne sont simplement pas interprétés correctement dans Oracle

  • La convention de dénomination "@" pour les variables est incompatible avec les paramètres nommés oracle. Il s'attend à voir ":" devant tous les paramètres

Quelqu'un at-il déjà rencontré cela et avoir des solutions de contournement?

Réponse acceptée

OMI, la bonne approche ici est de ne pas (selon la réponse acceptée) utilisent le préfixe de paramètre spécifique de base de données (donc @ pour sql-server, : pour Oracle) - mais plutôt: utiliser aucun préfixe du tout. Donc, en fin de compte, c'est:

il.Emit(OpCodes.Ldstr, prop.Name);

(etc)

En particulier, une propriété static serait mauvaise car elle vous limiterait à un fournisseur par AppDomain .

Dapper a été mis à jour avec ce changement. Il détecte également maintenant dynamiquement BindByName et le définit en conséquence (le tout sans avoir besoin d'une référence à OracleCommand ).


Réponse populaire

La résolution du problème de paramètre nommé s'est avérée être parce que les commandes Oracle nécessitent que le jeu de propriétés BindByName soit défini sur true. Pour résoudre ce problème, il a fallu modifier le SqlMapper lui-même. C'est un peu désagréable car le tweak n'est pas portable (il s'appuie sur une vérification de type pour une commande Oracle spécifique) mais cela fonctionne pour nos besoins pour le moment. La modification implique la mise à jour de la méthode SetupCommand, après avoir créé la commande à partir de l'objet de connexion que nous saisissons et définissons l'indicateur comme suit (~ ln 635):

var cmd = cnn.CreateCommand();
if (cmd is OracleCommand)
{
    ((OracleCommand)cmd).BindByName = true; // Oracle Command Only
}

Enfin, pour résoudre le problème du problème "@" à ":" dans les noms de paramètres, il fallait modifier la méthode CreateParamInfoGenerator. J'ai ajouté une chaîne statique - DefaultParameterCharacter définissant sa valeur sur ":" puis modifié ln 530 à partir de:

il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [c

à

il.Emit(OpCodes.Ldstr, DefaultParameterCharacter + prop.Name); // stack is now [parameters] [command] [name] (Changed @ to : for oracle)

et dans 546 de:

il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] (Changed @ to : for oracle)

à:

il.Emit(OpCodes.Ldstr, DefaultParameterCharacter + prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] (Changed @ to : for oracle)

Cela a permis à Dapper de fonctionner parfaitement avec les commandes Oracle




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi