Dapper는 SQL 2008 테이블 반환 매개 변수를 지원합니까?


답변:


91

이제 dapper에 구워진 테이블 값 매개 변수에 대한 직접 지원 (Dapper 1.26 이상)이 있습니다. 저장 프로 시저의 경우 데이터 유형이 sproc API에 내장되어 있으므로 다음을 제공하기 만하면됩니다 DataTable.

var data = connection.Query<SomeType>(..., new {
    id=123, name="abc", values = someTable
}, ...);

직접 명령 텍스트의 경우 두 가지 다른 옵션이 있습니다.

  • 도우미 메서드를 사용하여 사용자 지정 데이터 유형을 알려줍니다.

    var data = connection.Query<SomeType>(..., new {
        id=123, name="abc", values = someTable.AsTableValuedParameter("mytype")
    }, ...);
    
  • 사용할 사용자 정의 데이터 유형을 데이터 테이블 자체에 알립니다.

    someTable.SetTypeName("mytype");
    var data = connection.Query<SomeType>(..., new {
        id=123, name="abc", values = someTable
    }, ...);        
    

이들 중 어느 것이 든 잘 작동합니다.


Dapper를 사용하여 TVP를 추가 할 수없는 경우 동적 매개 변수를 사용하여 비 입력 매개 변수 추가가 필요한 경우 TVP를 추가 할 수 없습니다. @ stackoverflow.com/questions/33087629/ …
Mrinal Kamboj

9
Bah, IEnumerable 변환이 없습니까?
nuzzolilo

를 사용하면 ExecuteReader"System.Data.DataTable 형식의 멤버 이벤트는 매개 변수 값으로 사용할 수 없습니다."라는 메시지가 표시됩니다.
Ian Warburton

28

예, 우리는 그들을 지원하지만 여러분은 자신의 도우미를 코딩해야합니다.

예를 들면 :

class IntDynamicParam : Dapper.SqlMapper.IDynamicParameters
{
    IEnumerable<int> numbers;
    public IntDynamicParam(IEnumerable<int> numbers)
    {
        this.numbers = numbers;
    }

    public void AddParameters(IDbCommand command)
    {
        var sqlCommand = (SqlCommand)command;
        sqlCommand.CommandType = CommandType.StoredProcedure;

        List<Microsoft.SqlServer.Server.SqlDataRecord> number_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>();

        // Create an SqlMetaData object that describes our table type.
        Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) };

        foreach (int n in numbers)
        {
            // Create a new record, using the metadata array above.
            Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition);
            rec.SetInt32(0, n);    // Set the value.
            number_list.Add(rec);      // Add it to the list.
        }

        // Add the table parameter.
        var p = sqlCommand.Parameters.Add("@ints", SqlDbType.Structured);
        p.Direction = ParameterDirection.Input;
        p.TypeName = "int_list_type";
        p.Value = number_list;

    }
}

// SQL Server specific test to demonstrate TVP 
public void TestTVP()
{
    try
    {
        connection.Execute("CREATE TYPE int_list_type AS TABLE (n int NOT NULL PRIMARY KEY)");
        connection.Execute("CREATE PROC get_ints @ints int_list_type READONLY AS select * from @ints");

        var nums = connection.Query<int>("get_ints", new IntDynamicParam(new int[] { 1, 2, 3 })).ToList();
        nums[0].IsEqualTo(1);
        nums[1].IsEqualTo(2);
        nums[2].IsEqualTo(3);
        nums.Count.IsEqualTo(3);
        connection.Execute("DROP PROC get_ints");
        connection.Execute("DROP TYPE int_list_type");

    }
}

테이블 값 매개 변수에 대한 성능을 제대로 테스트해야합니다. int 목록을 전달하기 위해 이것을 테스트했을 때 여러 매개 변수를 전달하는 것보다 훨씬 느 렸습니다.

나는 contrib 프로젝트에서 dapper에 대한 SQL Server 특정 도우미를 갖는 것에 전적으로 반대하지는 않지만 핵심 dapper는 가능한 경우 공급 업체 특정 트릭을 추가하지 않습니다.


1
사실 TVP를 사용하는 것은 "where col in @values"보다 느립니다. 목록 지원 기능 (Dapper를 사용하면 IEnumerable <int>를 전달할 수 있고 쿼리를 자동으로 매개 변수화)을 사용하여 int 목록을 StoredProcedure에 전달할 수 있습니까?
Carlos Mendes 2011

이것은 dapper가 목록 지원에 사용하는 기술이 저장된 procs와 호환되지 않는 sps보다 일괄 처리가 더 빠른 경우 중 하나입니다
Sam Saffron

이것을 업데이트 할 수 있습니까? 최신 버전의 Dapper에서 identity 매개 변수를 무시해도 괜찮은지 알 수 없습니다.
Chris Pfohl

겠습니까 코드가 작동은 또는 의지가 필요를 IEnumerable <INT> 수집 TVP로 사용할 수에 대한 DataTable을로 변환하기
Mrinal Kamboj

11

이 티켓이 오래되고 매우 오래되었다는 것을 알고 있지만 일반 TVP를 지원하는 Dapper.Microsoft.Sql 패키지를 게시했음을 알려 드리고자합니다.

https://www.nuget.org/packages/Dapper.Microsoft.Sql/

샘플 사용 :

List<char> nums = this.connection.Query<char>(
  "get_ints", 
  new TableValuedParameter<char>(
    "@ints", "int_list_Type", new[] { 'A', 'B', 'C' })).ToList();

Dapper 테스트 프로젝트의 원래 클래스를 기반으로합니다.

즐겨!


다른 전형적인 유형의 매개 변수와 함께 매개 변수로 TVP를 갖는 방법을 이해하려고합니다. 어떻게 된 거죠?
Snowy

나는 아직 그 부분을 구현하지 않았습니다.
Darek

5

오늘 은 그렇지 않습니다. 실제로 건방진 "in"구현 ( where col in @values) 에 대한 테이블 검증 매개 변수를 조사 했지만 성능에 크게 영향을받지 않았습니다. 그러나 SPROC의 맥락에서는 의미가 있습니다.

가장 좋은 방법은 이 문제를 프로젝트 사이트에 문제기록하여 추적 / 우선 순위를 정하는 것입니다. 하지만 DbString 또는 DynamicParameters 옵션과 유사 할 수 있지만 수행 할 수있는 것처럼 들립니다.

그러나 오늘? 아니.


2
수정, 우리는 그것을 지원합니다 ... 당신은 그것을 직접 코딩해야합니다 :)
Sam Saffron
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.