makoラボ

日常や勉強会や技術ネタ

Dapperでテーブル値パラメータを使う

今関わっているプロジェクトでDapperを使ってるのですが、ストアドにテーブル値パラメータを使おうと思った時にちょっと分からなかったので調べてみました。

こちらのスタックオーバーフローにも書かれているようにDataTableを使えば渡せるようです。

例えば下記の様な定義のストアドがあった場合

CREATE TYPE dbo.UserTableType AS TABLE
    ( UserID int, UserName nvarchar(50) )

CREATE PROCEDURE spAddNewUser 
    (@tvpNewUser dbo.UserTableType READONLY)

Dapperでテーブル値パラメータを渡す場合のコードは

// パラメータとして渡すようにDataTableを準備
DataTable userTable = new DataTable();

userTable.TableName = "tvpNewUser";
userTable.Columns.Add("UserID", Type.GetType("System.Int32"));
userTable.Columns.Add("UserName", Type.GetType("System.String"));

// 登録するデータをDataTableにセット
for (int i = 1; i < 4; i++)
{
    DataRow row = dt.NewRow();
    row["UserID"] = i;
    row["UserName"] = "新しいユーザ" + i;
    dt.Rows.Add(row);
}

// パラメータとしてDataTableを渡してストアドを実行する
var data = connection.Query<SomeType>("spAddNewUser", new { tvpNewUser = userTable
}, ...);

こんな感じでDataTableを作成して渡せばちゃんとストアド側でパラメータとして受け取れるようです。

でもなんかスマートじゃないのでもうちょっとうまいこと出来ないものか・・・