대퍼 매개 변수가 작동하지 않습니다.

c# dapper

문제

Dapper orm을 다음과 같은 간단한 쿼리와 함께 사용하려고합니다.

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
    });            

그러나 존재하는 것으로 알려진 accountNumber를 사용하여 이것을 실행하면 dapper는 아무 것도 반환하지 않습니다. 그래서 따옴표를 제거하여 매개 변수가 실제로 계정 번호로 대체되는지 확인하려고 시도했지만 서버에서 반환되는 오류는 "@ZYX"주위에 구문 오류가 있음을 나타냅니다. 즉, dapper는 주어진 값으로 매개 변수를 대체하지 않습니다. 왜 이런 일이 일어나고 있는거야? 밖에있는 제한된 문서에서 이것은 '잘 작동합니다'.


편집 1

이걸 작동시키지 못했습니다. string.format을 사용하여 매개 변수를 해결 방법으로 삽입하십시오.

수락 된 답변

여기에는 두 가지 문제가 있습니다. 첫째로 (당신이 질문에 이것을 적어 where a.acct = '@ZYX' 음에도 불구하고) SQL 규칙 하에서 where a.acct = '@ZYX' 는 어떤 매개 변수도 사용하지 않고 - @ 기호를 포함하는 리터럴 문자열과 일치하는 것으로 보입니다. SQL Server의 경우 (아래 참고 참조) 올바른 사용법은 where a.acct = @ZYX 입니다.

하나! OdbcConnection 을 사용하고 있으므로 명명 된 매개 변수 가 적용되지 않습니다 . 실제로 SQL-Server와 같은 제품에 연결하는 경우에는 ODBC보다 우수한 기능과 성능을 갖춘 순수 ADO.NET 클라이언트를 사용하는 것이 좋습니다. 그러나 ODBC가 유일한 옵션 인 경우 명명 된 매개 변수를 사용하지 않습니다 . 며칠 전까지 만해도 큰 문제가 있었지만 OleDb를 사용하여 Dapper에서 쿼리 매개 변수를 전달할 때 코드 (아직 NuGet 패키지는 아님)가 이제 ODBC를 지원합니다. 소스에서 빌드하거나 다음 릴리스를 기다리는 경우 다음을 사용할 수 있어야합니다.

...
where a.acct = ?

당신의 명령에, 그리고 :

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

이름 (참고 anythingYouLike ...) ODBC 사용하지 않습니다, 그래서 수 있습니다 당신이 좋아하는 것을. 보다 복잡한 시나리오에서 예를 들면 다음과 같습니다.

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

dapper는 익명 유형을 구현하여 값의 원래 순서를 이해하여 올바른 순서 ( id , name , when )로 명령에 추가되도록 일부 지식을 사용합니다.

마지막 관찰 :

즉, dapper는 주어진 값으로 매개 변수를 대체하지 않습니다.

Dapper는 매개 변수를 주어진 값으로 대체 하지 않습니다 . 이는 단순히 sql을 매개 변수화하는 올바른 방법이 아닙니다. 매개 변수는 일반적으로 별도로 전송되므로 다음을 보장합니다.

  • SQL 주입 위험이 없다.
  • 최대 쿼리 계획 재사용
  • 서식 지정 문제 없음

일부 ADO.NET / ODBC 공급자 는 이론적으로 대체를 통해 내부적으로 구현 하도록 선택할 수 있지만 이는 dapper와 별개입니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.