2016-07-06 1 views
1

저는 IN 절에 대한 쿼리 매개 변수의 자동 확장을 위해 Dapper (v1.42) 지원을 사용하려고합니다. 내 쿼리는 다음과 같습니다Dapper의 IN 절 지원에 대한 잘못된 정의는 무엇입니까?

var records = db.Query(
    "SELECT [IdCol], [OtherCol], [TinyIntCol], [TextCol] FROM [Tbl] WHERE [FilterCol] = @filterVal AND [TinyIntCol] IN @byteVals", 
    new { filterVal = ..., byteVals = flag ? new byte[] { Constants.Byte1, Constants.Byte2 } : new byte[] { Constants.Byte1 } } 
); 

하지만 그 System.Data.SqlClient.SqlException (0x80131904) 결과 : 근처의 구문이 잘못되었습니다 '@byteVals을'.

나는 틀린 일을해야합니다. 그러나 나는 무엇을 확신하지 못합니다. 어떤 바보 같은 짓을하는지 말해줘. 고맙습니다!

답변

1

문제는 바이트 배열을 사용할 때 Dapper가 항상 바이트 배열을 단일 이진 값으로 전달합니다. 쿼리 텍스트에 "IN"절이 있으면이 변경 사항이 적용되지 않습니다 (@Damien_The_Unbeliever의 주석 참조).). 여기서 실패

var results = db.Query<Product>(
    "SELECT * FROM Products WHERE ProductId IN @ids", 
    new 
    { 
     ids = new [] { 1, 2 } // This works (int array) 
    } 
); 

..하지만 다음 - 매개 변수 확장은 int 배열과 협력하고 있기 때문에 (나는 손에 것을 가지고 있기 때문에, NORTHWND 데이터베이스를 기반으로)

다음 작품을 설명하기 위해

exec sp_executesql 
    N'SELECT * FROM Products WHERE ProductId IN (@ids1,@ids2)', 
    N'@ids1 int,@ids2 int', 
    @ids1=1, 
    @ids2=2 
: SQL 프로파일 러, 다음 쿼리의 첫 번째 INT 배열 방식의 결과를 사용

var results = db.Query<Product>(
    "SELECT * FROM Products WHERE ProductId IN @ids", 
    new 
    { 
     ids = new byte[] { 1, 2 } // This fails (byte array) 
    } 
); 

- 그것은 바이트 배열을 전달하려고

전달되는 개별 매개 변수를 명확하게 볼 수 있습니다.

다음 쿼리 바이트 어레이 접근 결과

에서, "@ids"파라미터 오히려 개개로 확장되기보다는, 하나의 값으로 전달되고 여기서
exec sp_executesql 
    N'SELECT * FROM Products WHERE ProductId IN @ids', 
    N'@ids varbinary(2)', 
    @ids=0x0102 

-이 야기되는 것이다 너의 문제.

바이트 배열을 채우기 위해 바이트 값을 사용하여 문제를 해결할 수 있어야합니다.

+0

이 문제는 바이트 배열에 이미 SQL 데이터 형식에 대한 매핑이 완벽하다는 사실에서 비롯된 것 같습니다. –

+0

@Damien_The_Unbeliever 아, 맞아요! "IN"절에 여러 값이 필요하다는 쿼리를 사람이 읽는 것이 명백 할 수도 있지만, 쿼리 텍스트를 구문 분석하여 Dapper에서이를 감지하는 것은 불가능할 것이라고 생각합니다. 더하기, 매개 변수 유형은 다음과 같이 다양합니다. 맥락에서 보면, 대부분의 시간 동안 "마술에 의한"일보다는 논란의 여지가있다. 배열에 대한 캐스트 해결 방법은 여기에서 문제를 해결하는 가장 좋은 방법이라고 생각합니다. –