Dapper で SQL Server の date 型の値をパラメータとして渡したい

2016/09/17 コード修正しました


を見かけたのでちょっと書いてみる。

何もしていないと、.NET の DateTime は Dapper で DbType.DateTime 扱いなので、以下のような問題が出る。
DapperでDateTime2 - Qiita

上の Qiita でも対応策書いてるけど、個人的には Dapper の DbString を真似たクラスを作って対応してます。

public class DbDate : ICustomQueryParameter {
  public DateTime? Value { get; set; }
  public void AddParameter(IDbCommand command, string name) {
    var param = command.CreateParameter();
    param.ParameterName = name;
    param.Value = Value.HasValue ? (object)Value.Value.Date : DBNull.Value;
    // DbType はダメで、SqlDbType じゃないとダメでした。 
    // https://msdn.microsoft.com/ja-jp/library/cc716729(v=vs.110).aspx ではいけそうですが。。
    var p = param as SqlParameter;
    if (p != null) {
      p.SqlDbType = SqlDbType.Date;
    }
    else {
      param.DbType = DbType.Date;
    }
    command.Parameters.Add(param);
  }
}

使う時はこんな感じ。*1

var query = @"select top(1) [Id] 
from [Hoge] 
where [Hoge日] = @Hoge日";
  
var id = conn.ExecuteScale<int>(query, new {
  Hoge日 = new DbDate { Value = DateTime.UtcNow }
}); 

雰囲気伝わるかな? datetime2 も同じで DbDateTime2 作ってます。

*1:コンパイル通してないから動かなかったらゴメン