Dapper doit déclarer la variable scalaire

c# dapper parameterized-query sql

Question

Je rencontre des problèmes lors de la tentative d'utilisation d'une requête paramétrée dans Dapper. J'ai trouvé un certain nombre d'utilisateurs ayant des problèmes similaires, mais je n'ai pas pu résoudre le problème.

Le code

    public User GetUser(int employeeId)
    {
        var args = new
        {
            EmployeeId = employeeId
        };

        const string sql = @"
                    select 
                        first_name 'FirstName', 
                        last_name 'LastName'
                    from 
                        users 
                    where 
                        employee_id = @EmployeeId 
                ";

        using (var con = MakeConnection())
        {
            var r = con.Query<User>(sql, args);
            return r.FirstOrDefault();
        }
    }

L'erreur

A first chance exception of type 'System.Data.Odbc.OdbcException' occurred in System.Data.dll

Additional information: ERROR [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Must declare the scalar variable "@EmployeeId".

J'ai également essayé d'utiliser DynamicParameters et de le transmettre à la place, mais cela ne fonctionne pas non plus

var p = new DynamicParameters();
p.Add("@EmployeeId", employeeId); // I have also tried without the @
//...
var r = con.Query<User>(sql,p);

Réponse acceptée

Il y a deux problèmes ici; premièrement (bien que vous notiez ceci dans votre question) where a.acct = '@ZYX' , sous les règles SQL, n'utilise aucun paramètre - il semble correspondre à la chaîne littérale qui contient un signe @ . Pour SQL-Server (voir note ci-dessous), l'utilisation correcte serait where a.acct = @ZYX .

Toutefois! Puisque vous utilisez OdbcConnection , les paramètres nommés ne s’appliquent pas . Si vous vous connectez à quelque chose comme SQL-Server, je vous recommande fortement d'utiliser les clients ADO.NET purs, qui offrent de meilleures fonctionnalités et performances que ODBC. Cependant, si ODBC est votre seule option: il n’utilise pas de paramètres nommés . Jusqu'à il y a quelques jours, cela aurait représenté un problème majeur, mais selon les paramètres de la requête Passing dans Dapper utilisant OleDb , le code (mais pas encore le package NuGet) supporte maintenant ODBC. Si vous construisez à partir de la source (ou attendez la prochaine version), vous devriez pouvoir utiliser:

...
where a.acct = ?

dans votre commande, et:

var result = connection.Query(sqlString.ToString(),
new {
    anythingYouLike = accountNumber
});

Notez que le nom ( anythingYouLike ) n'est pas utilisé par ODBC, donc peut être ... tout ce que vous voulez . Dans un scénario plus complexe, par exemple:

.Execute(sql, new { id = 123, name = "abc", when = DateTime.Now });

dapper utilise certaines connaissances sur la manière dont les types anonymes sont implémentés pour comprendre l'ordre d'origine des valeurs, afin qu'elles soient ajoutées à la commande dans l'ordre correct ( id , name , when ).

Une dernière observation:

Ce qui signifie que Dapper ne remplace pas le paramètre par sa valeur donnée.

Dapper ne remplace jamais les paramètres par leur valeur donnée. Ce n'est tout simplement pas la bonne façon de paramétrer sql: les paramètres sont généralement envoyés séparément, ce qui garantit:

  • il n'y a pas de risque d'injection SQL
  • réutilisation maximale du plan de requête
  • pas de problèmes de formatage

Notez que certains fournisseurs ADO.NET / ODBC pourraient théoriquement choisir d'implémenter des choses en interne via le remplacement - mais cela est distinct de dapper.



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