web-dev-qa-db-ja.com

Dapper.TVPTableValueParameterを他のパラメーターと一緒に使用する

他のパラメータとともに、テーブル値のパラメータを受け取るプロシージャがあります。

_CREATE PROCEDURE [dbo].[Update_Records]
    @currentYear INT,
    @country INT,
    @records Record_Table_Type READONLY
AS
_

そしてこれをDapper.TVPで呼び出そうとしています。

これが私がこれまでに持っているコードです:

_        var recordsParameter = new List<SqlDataRecord>();

        // This metadata matches 'Record_Table_Type' in the Database
        var recordsMetaData = new[]
        {
            new SqlMetaData("OriginalValue", SqlDbType.Decimal, 19, 4),
            new SqlMetaData("NewValue", SqlDbType.Decimal, 19, 4),
            new SqlMetaData("NewPercent", SqlDbType.Decimal, 7, 2),
        };

        foreach (var r in records)
        {
            var record = new SqlDataRecord(recordsMetaData);
            record.SetDecimal(0, r.OriginalValue);
            record.SetDecimal(1, r.NewValue);
            record.SetDecimal(2, r.NewPercent);
            recordsParameter.Add(record);
        }

        var spParams = new DynamicParameters(new
        {
            currentYear = filter.currentYear,
            country = filter.country,
        });

        var recordsParam = new TableValueParameter("@records", "Record_Table_Type", recordsParameter);

        using (var connection = ConnectionFactory.GetConnection())
        {
            connection.Execute("Update_Records", ???, commandType: CommandType.StoredProcedure);
        }
_

私の問題は、Dapper Execute()の呼び出しで、両方のパラメーターセットをプロシージャに渡す方法です。

私が試してみました:

_var spParams = new DynamicParameters(new
{
    currentYear = filter.currentYear,
    country = filter.country,
    records = new TableValueParameter("@records", "Record_Table_Type", recordsParameter);
});

connection.Execute("Update_Records", spParams, commandType: CommandType.StoredProcedure);
_

そして

_connection.Execute("Update_Records", new Object[] { spParams, recordsParam }, commandType: CommandType.StoredProcedure);
_

どちらもプロシージャを呼び出しますが、空のテーブルパラメータを渡します(SELECT COUNT(*) FROM @recordsは0を返します)

Dapper.TVPの実際のドキュメントやソースが見つからないため、全体が非常に混乱しています。また、.Execute()の2番目のパラメーターはdynamicであるため、ここでも私がそれに渡すことができるものとできないものを教えてはいけません。

何か案は?

18
CodingWithSpike

私はモバイルを使用していて、質問を誤解している可能性がありますが、これは次のようになります。

DataTable records = ...
connection.Execute("Update_Records",
    new {
        currentYear = filter.currentYear,
        country = filter.country,
        records
    },
    commandType: CommandType.StoredProcedure
);
14
Marc Gravell

ここでのMarkGravellからの回答に基づく: DapperはSQL 2008テーブル値パラメーターをサポートしていますか?

Dapper.TVPを使用せず、代わりにDataTableを使用するようにコードを変更したため、コードは次のようになります。

        var recordsTable = new DataTable();
        recordsTable.Columns.Add("NewValue", typeof(Decimal));
        foreach (var netRevenue in records)
        {
            var row = recordsTable.NewRow();
            row[0] = netRevenue.NewValue;
            recordsTable.Rows.Add(row);
        }
        recordsTable.EndLoadData();

        var spParams = new DynamicParameters(new
        {
            currentYear = filter.currentYear,
            country = filter.country,
            records = recordsTable.AsTableValuedParameter("Record_Table_Type")
        });

        using (var connection = ConnectionFactory.GetConnection())
        {
            connection.Execute("Update_Records", spParams, commandType: CommandType.StoredProcedure);
        }

そして、これは機能します。

7
CodingWithSpike