Los parámetros Dapper no funcionan

c# dapper

Pregunta

Estoy tratando de usar Dapper orm con la siguiente consulta simple:

var sqlString = new StringBuilder();
sqlString.Append("select a.acct AccountNumber,");
sqlString.Append("       b.first_name FirstName,");
sqlString.Append("       b.last_name LastName,");
sqlString.Append("       a.rr RrNumber,");
sqlString.Append("       c.addr1 AddressLine1,");
sqlString.Append("       c.addr2 AddressLine2,");
sqlString.Append("       c.addr3 AddressLine3,");
sqlString.Append("       c.addr4 AddressLine4,");
sqlString.Append("       c.addr5 AddressLine5,");
sqlString.Append("       c.addr6 AddressLine6,");
sqlString.Append("       c.addr7 AddressLine7,");
sqlString.Append("       c.addr8 AddressLine8 ");
sqlString.Append("from (pub.mfclac as a left join pub.mfcl as b on a.client=b.client) ");
sqlString.Append("left join pub.mfclad as c on a.client=c.client ");
sqlString.Append("where a.acct = '@ZYX'");

var connection = new OdbcConnection(_connectionString);

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

Sin embargo, cuando ejecuto esto con un número de cuenta que se sabe existe, dapper no devuelve nada. Así que traté de eliminar las comillas para verificar que el parámetro en realidad está siendo reemplazado por el número de cuenta, sin embargo, el error que se devuelve desde el servidor indica un error de sintaxis alrededor de "@ZYX". Lo que significa que dapper no está reemplazando el parámetro con su valor dado. ¿Alguna idea de por qué está pasando esto? De la documentación limitada que hay, esto debería 'solo funcionar'.


Edit1

No pude hacer que esto funcione. Usando string.format para insertar el parámetro como una solución alternativa.

Respuesta aceptada

Hay dos problemas aquí; en primer lugar (aunque se nota esto en su pregunta) where a.acct = '@ZYX' , bajo las reglas de SQL, no hace uso de ningún parámetro; parece coincidir con la cadena literal que, por casualidad, incluye un signo @ . Para SQL-Server (ver nota a continuación), el uso correcto sería where a.acct = @ZYX .

¡Sin embargo! Como usa OdbcConnection , los parámetros nombrados no se aplican . Si en realidad se está conectando a algo así como SQL-Server, recomendaría encarecidamente utilizar los clientes ADO.NET puros, que tienen mejores características y rendimiento que ODBC. Sin embargo, si ODBC es su única opción, no usa parámetros nombrados . Hasta hace unos días, esto habría representado un problema importante, pero según Pasar los parámetros de consulta en Dapper utilizando OleDb , el código (pero aún no el paquete NuGet) ahora es compatible con ODBC. Si compila desde la fuente (o espera la próxima versión), debería poder usar:

...
where a.acct = ?

en tu comando, y:

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

Tenga en cuenta que ODBC no usa el nombre ( anythingYouLike ), por lo que puede ser ... cualquier cosa que desee . En un escenario más complejo, por ejemplo:

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

Dapper utiliza algunos conocimientos sobre cómo se implementan los tipos anónimos para comprender el orden original de los valores, de modo que se agreguen al comando en la secuencia correcta ( id , name , when ).

Una observación final:

Lo que significa que dapper no está reemplazando el parámetro con su valor dado.

Dapper nunca reemplaza los parámetros con su valor dado. Esa no es la forma correcta de parametrizar SQL: los parámetros generalmente se envían por separado, lo que garantiza:

  • no hay riesgo de inyección SQL
  • reutilización máxima del plan de consulta
  • sin problemas de formateo

Tenga en cuenta que algunos proveedores de ADO.NET / ODBC teóricamente podrían optar por implementar cosas internamente a través del reemplazo, pero eso es independiente de Dapper.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow