OleDb를 사용하여 Dapper에서 쿼리 매개 변수 전달

dapper oledb

문제

이 쿼리는 No value given for one or more required parameters 오류를 생성합니다.

using (var conn = new OleDbConnection("Provider=..."))
{
  conn.Open();
  var result = conn.Query(
    "select code, name from mytable where id = ? order by name",
    new { id = 1 });
}

쿼리 문자열을 ... where id = @id ... 변경하면 오류가 발생합니다. Must declare the scalar variable "@id".

어떻게 쿼리 문자열을 구성하고 매개 변수를 전달합니까?

수락 된 답변

현재 소스 코드 (아직 NuGet에 공개되지 않음)가이 문제를 해결합니다. 다음과 같이 작동합니다.

var result = conn.Query(
"select code, name from mytable where id = ?id? order by name",
new { id = 1 });

전문가 답변

중요 : 새로운 답변보기


현재 빌드에서 그 대답은 다음 두 가지 이유로 "아니오"입니다.

  • 이 코드는 사용되지 않는 매개 변수를 필터링하려고 시도합니다. 현재 SQL에서 @id , :id 또는 ?id 와 같은 것을 찾을 수 없으므로 코드를 모두 제거하고 있습니다 :id
  • 형식에서 값을 추가하는 코드는 리플렉션이 멤버의 순서를 보장하지 않으므로 매개 변수에 대해 임의의 (잘, 확인 : 알파벳순) 순서를 사용하므로 위치 익명 인수가 불안정합니다.

좋은 소식은이 두 가지 모두 고칠 수 있다는 것입니다.

  • 필터링 동작을 조건부로 만들 수 있습니다.
  • 우리는 모든 속성 이름과 일치하는 생성자가있는 유형의 카테고리를 감지하고 생성자 인수 위치를 사용하여 속성의 합성 순서를 결정할 수 있습니다. 익명 유형은이 카테고리에 속합니다

로컬 복제본을 변경하면 다음과 같이 처리됩니다.

// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
    using (var conn = new System.Data.OleDb.OleDbConnection(
        Program.OleDbConnectionString))
    {
        var row = conn.Query("select Id = ?, Age = ?", new DynamicParameters(
            new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
        ) { RemoveUnused = false } ).Single();
        int age = row.Age;
        int id = row.Id;
        age.IsEqualTo(23);
        id.IsEqualTo(12);
    }
}

현재 DynamicParameters 사용하여 Query / Query<T> 과부하를 추가하지 않으려 고합니다. 이는 상당한 수의 메소드에 추가해야 할 필요가 있기 때문입니다. DynamicParameters 추가하면 한 곳에서 해결됩니다.

내가 이것을 강요하기 전에 의견에 개방적입니다 - 당신에게 유용 할 것 같습니까?


편집 : 펑키 smellsLikeOleDb (아니오, 농담이 아님)를 추가하여 이제이 작업을보다 직접 수행 할 수 있습니다.

// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
    using (var conn = new System.Data.OleDb.OleDbConnection(
        Program.OleDbConnectionString))
    {
        var row = conn.Query("select Id = ?, Age = ?",
            new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
        ).Single();
        int age = row.Age;
        int id = row.Id;
        age.IsEqualTo(23);
        id.IsEqualTo(12);
    }
}


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