"여러 번 명령을 실행"하는 기능으로 인해 데이터베이스로의 다중 왕복 이동이 발생합니까?

dapper

문제

Dapper 설명서 에서 IEnumerable 매개 변수를 사용하여 여러 번 명령을 실행할 수 있다고합니다. 다음 예제를 제공합니다.

connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
).IsEqualTo(3); // 3 rows inserted: "1,1", "2,2" and "3,3"

이로 인해 데이터베이스 ( IEnumerable<T> 의 각 T 에 하나씩)로 다중 라운드 트립이 발생합니까? 또는 Dapper는 여러 쿼리를 배치로 변환하고 왕복을 1 회 수행 할만큼 충분히 똑똑합니까? 설명서에서는 일괄 적으로로드하는 예제를 사용하므로 단 한 번의 왕복 이동 만하는 것으로 추측되지만 성능에 민감한 코드에 사용하기 전에 확실하게 알고 싶습니다.

후속 질문으로, 첫 번째 답변에 따라 거래가 어떻게 처리되는지 궁금 할 것입니다. 즉 전체 집합에 대한 하나의 트랜잭션이있다 T 의, 또는 당 하나의 트랜잭션 T ?

수락 된 답변

마침내 나는 이것을 다시 보았습니다. 소스 코드 ( \Dapper\SqlMapper.cs )를보고 ExecuteImpl 메서드에서 다음 스 니펫을 발견했습니다.

// ...
foreach (var obj in multiExec)
{
    if (isFirst)
    {
        masterSql = cmd.CommandText;
        isFirst = false;
        identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null);
        info = GetCacheInfo(identity, obj, command.AddToCache);
    }
    else
    {
        cmd.CommandText = masterSql; // because we do magic replaces on "in" etc
        cmd.Parameters.Clear(); // current code is Add-tastic
    }
    info.ParamReader(cmd, obj);
    total += cmd.ExecuteNonQuery();
}
// ...

흥미로운 부분은 ExecuteNonQuery 가 호출되는 두 번째 마지막 행에 있습니다. 이 메서드는 for 루프를 반복 할 때마다 호출되므로 set 기반 연산이라는 의미에서 일괄 처리되지 않습니다. 따라서 여러 번의 왕복이 필요합니다. 그러나 모든 작업이 동일한 연결에서 수행되고 지정된 경우 동일한 트랜잭션 내에서 수행된다는 의미에서 일괄 처리됩니다.

집합 기반 작업을 수행하는 유일한 방법은 관심있는 개체에 대해 데이터베이스에 사용자 지정 테이블 값 형식을 만드는 것입니다. 그런 다음 .NET 코드에서 일치하는 이름과 형식을 포함하는 DataTable 개체를 명령 매개 변수로 전달합니다. 모든 개체에 대해 테이블 ​​반환 형식을 만들 필요없이이 작업을 수행 할 수있는 방법이 있다면 그 정보를 듣고 싶습니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow