수색…


매개 변수

매개 변수 세부
this cnn 기본 데이터베이스 연결 - this 확장 메소드를 나타냅니다. 연결이 열려 있지 않아도됩니다. 열려 있지 않으면 자동으로 열리고 닫힙니다.
<T> / Type (옵션) 반환 할 객체의 유형. 비 제네릭 / 비 Type API를 사용하는 경우 행당 dynamic 객체가 반환되어 쿼리에서 반환 된 열 이름별로 속성이 시뮬레이트됩니다.이 dynamic 객체는 IDicionary<string,object> 도 구현 IDicionary<string,object> .
sql 실행할 SQL
param (선택 사항) 포함 할 매개 변수.
transaction (선택 사항) 명령과 연결할 데이터베이스 트랜잭션
buffered (선택 사항) 목록에 데이터를 미리 사용할지 (기본값), 라이브 판독기에서 열려있는 IEnumerable 을 표시할지
commandTimeout (선택 사항) 명령에 사용할 시간 제한. 지정하지 않으면 SqlMapper.Settings.CommandTimeout 이 가정됩니다 (지정된 경우).
commandType 수행되는 명령의 유형. 기본값은 CommandText

비고

매개 변수를 표현하기위한 구문은 RDBMS마다 다릅니다. 위의 모든 예제는 SQL Server 구문 즉 @foo . 그러나, ?foo:foo 도 잘 동작해야합니다.

기본 매개 변수가있는 SQL

Dapper를 사용하면 완전히 매개 변수화 된 SQL을 사용하여 모범 사례를 쉽게 따르게됩니다.

바비 테이블

매개 변수가 중요하므로 dapper를 사용하면 쉽게 이해할 수 있습니다. RDBMS (보통 @foo ?foo 또는 :foo )에 대한 일반적인 방법으로 매개 변수를 표현하고 foo 라는 멤버가있는 객체를 dapper에 제공하면됩니다. 이 작업을 수행하는 가장 일반적인 방법은 익명 형식입니다.

int id = 123;
string name = "abc";
connection.Execute("insert [KeyLookup](Id, Name) values(@id, @name)",
    new { id, name });

그리고 그게 다야. Dapper가 필수 매개 변수를 추가하고 모든 것이 작동합니다.

개체 모델 사용

기존 개체 모델을 매개 변수로 사용할 수도 있습니다.

KeyLookup lookup = ... // some existing instance
connection.Execute("insert [KeyLookup](Id, Name) values(@Id, @Name)", lookup);

Dapper는 command-text를 사용하여 추가 할 개체의 멤버를 결정합니다. Description , IsActive , CreationDate 와 같은 불필요한 것들을 추가하지는 않습니다. 우리가 발행 한 명령에 분명히 포함되어 있지 않기 때문에 필요하지 않습니다. 예를 들어 명령에 다음이 포함 된 경우

// TODO - removed for now; include the @Description in the insert

위의 내용이 단지 주석 일 뿐이라는 것을 알아 내려하지 않습니다.

저장 프로 시저

저장 프로 시저에 대한 매개 변수는 정확히 동일하게 작동하지만, dapper는 포함해야 할 대상을 결정할 수 없습니다. 사용 가능한 모든 것이 매개 변수로 처리됩니다. 따라서 익명 형식이 일반적으로 선호됩니다.

connection.Execute("KeyLookupInsert", new { id, name },
    commandType: CommandType.StoredProcedure);

값 인라이닝

때로는 매개 변수의 편의성 (유지 관리 및 표현력면에서)이 매개 변수로 취급하기위한 성능 비용보다 중요 할 수 있습니다. 예를 들어 페이지 크기가 구성 설정에 의해 고정 된 경우. 또는 상태 값이 enum 값과 일치합니다. 중히 여기다:

var orders = connection.Query<Order>(@"
select top (@count) * -- these brackets are an oddity of SQL Server
from Orders
where CustomerId = @customerId
and Status = @open", new { customerId, count = PageSize, open = OrderStatus.Open });

여기서 유일한 실제 매개 변수는 customerId . 다른 두 매개 변수는 실제로 변경되지 않는 의사 매개 변수입니다. 종종 RDBMS는 이것을 상수로 감지하면 더 나은 작업을 수행 할 수 있습니다. Dapper에는 숫자 형식 에만 적용되는 @name 대신에 - {=name} 특수 구문이 있습니다. SQL 인젝션으로 인해 공격 대상이 최소화됩니다. 예를 들면 다음과 같습니다.

var orders = connection.Query<Order>(@"
select top {=count} *
from Orders
where CustomerId = @customerId
and Status = {=open}", new { customerId, count = PageSize, open = OrderStatus.Open });

Dapper는 SQL을 실행하기 전에 값을 리터럴로 대체하므로 RDBMS는 실제로 다음과 같이 표시됩니다.

select top 10 *
from Orders
where CustomerId = @customerId
and Status = 3

이는 특히 RDBMS 시스템이 더 나은 결정을 내리는 것이 아니라 실제 매개 변수가 방지하는 쿼리 계획을 열 때 유용합니다. 예를 들어, 컬럼 술어가 매개 변수에 대 한 경우, 해당 컬럼에 특정 값을 갖는 필터링 된 인덱스를 사용할 수 없습니다. 이는 다음 질의에 지정된 값 중 하나와 다른 매개 변수가있을 수 있기 때문입니다.

리터럴 값을 사용하면 쿼리 최적화 프로그램은 필터링 된 인덱스를 사용할 수 있습니다. 이후의 쿼리에서 값을 변경할 수 없다는 것을 알고 있기 때문입니다.

목록 확장

데이터베이스 쿼리의 일반적인 시나리오는 IN (...) 입니다. IN (...) 목록은 런타임에 생성됩니다. 대부분의 RDBMS에는 이에 대한 좋은 은유가 없으며이를위한 범용 교차 RDBMS 솔루션은 없습니다. 대신 dapper는 자동 명령 확장 기능을 제공합니다. 필요한 모든 것은 IEnumerable 제공된 매개 변수 값입니다. @foo 가 포함 된 명령은 (@foo0,@foo1,@foo2,@foo3) (4 개 항목의 순서에 대해) 확장됩니다. 이것의 가장 일반적인 사용법은 IN .

int[] orderIds = ...
var orders = connection.Query<Order>(@"
select *
from Orders
where Id in @orderIds", new { orderIds });

그런 다음 다중 행 가져 오기에 적합한 SQL을 발행하도록 자동으로 확장됩니다.

select *
from Orders
where Id in (@orderIds0, @orderIds1, @orderIds2, @orderIds3)

@orderIds0 등의 매개 변수가 arrray에서 가져온 값으로 추가됩니다. 이 기능이 실수로 사용되지 않았는지 확인하기 위해 유효하지 않은 SQL이 의도적으로 사용된다는 사실에 유의하십시오. 이 기능은 SQL Server의 OPTIMIZE FOR / UNKNOWN 쿼리 힌트와도 올바르게 작동합니다. 당신이 사용하는 경우 :

option (optimize for
    (@orderIds unknown))

이를 올바르게 확장합니다.

option (optimize for
    (@orderIds0 unknown, @orderIds1 unknown, @orderIds2 unknown, @orderIds3 unknown))

여러 입력 세트에 대한 조작 수행

때로는 같은 일을 여러 번하고 싶어합니다. Dapper는 가장 바깥 쪽 매개 변수 (일반적으로 단일 익명 형식 또는 도메인 모델 인스턴스)가 실제로 IEnumerable 시퀀스로 제공되는 경우 Execute 메서드에서이 메서드를 지원합니다. 예 :

Order[] orders = ...
// update the totals
connection.Execute("update Orders set Total=@Total where Id=@Id", orders);

여기, dapper는 우리의 데이터에서 간단한 반복을하고 있습니다.

Order[] orders = ...
// update the totals
foreach(Order order in orders) {
    connection.Execute("update Orders set Total=@Total where Id=@Id", order);
}

이 사용법은 모든 "다중 활성 결과 집합"에 명시 적으로 구성된 연결에서 async API와 결합 할 때 특히 유용합니다 .이 사용법에서는 dapper가 자동으로 작업을 파이프 라인 처리하므로 행당 대기 시간 비용을 지불하지 않습니다. 이렇게하려면 약간 더 복잡한 사용법이 필요합니다.

await connection.ExecuteAsync(
    new CommandDefinition(
        "update Orders set Total=@Total where Id=@Id", 
         orders, flags: CommandFlags.Pipelined))

그러나 테이블 값 매개 변수를 조사 할 수도 있습니다.

의사 위치 매개 변수 (명명 된 매개 변수를 지원하지 않는 공급자 용)

일부 ADO.NET 공급자 (특히 : OleDB)는 명명 된 매개 변수를 지원하지 않습니다. 매개 변수는 대신 위치에 의해서만 지정되며 ? 장소 소유자. Dapper는 어떤 멤버를 사용할 지 알지 못하기 때문에 dapper는 대체 구문을 허용 ?foo? ; 이것은 dapper가 매개 변수 토큰을 완전히 대체 한다는 것을 제외하고는 다른 SQL 변형에서 @foo 또는 :foo 와 동일 할 것입니다 ? 쿼리를 실행하기 전에

이것은 목록 확장과 같은 다른 기능과 함께 작동하므로 다음 내용이 유효합니다.

string region = "North";
int[] users = ...
var docs = conn.Query<Document>(@"
     select * from Documents
     where Region = ?region?
     and OwnerId in ?users?", new { region, users }).AsList();

.region.users 회원 따라 사용되며, 발행 된 SQL (3 사용자, 예를 들어)입니다 :

     select * from Documents
     where Region = ?
     and OwnerId in (?,?,?)

그러나 dapper 에서는 이 기능을 사용할 때 동일한 매개 변수를 여러 번 사용할 수 없습니다 . 이는 동일한 매개 변수 값 (큰 값일 수 있음)을 여러 번 추가하지 않아도되도록하기위한 것입니다. 동일한 값을 여러 번 참조해야하는 경우 다음과 같이 변수 선언을 고려하십시오.

declare @id int = ?id?; // now we can use @id multiple times in the SQL

변수를 사용할 수없는 경우 매개 변수에 중복 된 멤버 이름을 사용할 수 있습니다. 이렇게하면 값이 여러 번 전송된다는 것을 분명히 알 수 있습니다.

int id = 42;
connection.Execute("... where ParentId = $id0$ ... SomethingElse = $id1$ ...",
      new { id0 = id, id1 = id });


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow