DapperはSingleOrDefault(DATEDIFF(...))にnullを返します。

asp.net-mvc-3 dapper sql-server-2008

質問

私は次のようなSQL文を持っています:

SELECT DATEDIFF(Day, startDate, endDate) FROM Data WHERE ProjectId=@id

DataProjectIdレコードがない場合、SQL Serverはnullを返します。

Dapperでは、次の方法でこれを実行します。

value = conn.Query<int>("...").SingleOrDefault()

この場合、 SingleOrDefaultのセマンティクスは「これがnullの場合はゼロを返す」ことを意味します。実際には、私のコードはもっと使い勝手が悪いです。

int toReturn = 0;
using (var conn = ...) {
  toReturn = conn.Query<int>("SELECT DATEDIFF(...))");
}
return toReturn;

私がこのコードをデバッグしてステップすると、ライン・yield return (T)func(reader)がヌル・ポインタ例外をスローしていることがわかります。

私はここで何か間違っているのですか、これは設計上のものですか?

(参考、回避ISNULL(..., 0)私の選択をISNULL(..., 0)囲むことです)

受け入れられた回答

DataにProjectIdのレコードがない場合、SQL Serverはnullを返します。

Data一致するレコードがない場合、SQL Serverは実際にはnullを返しません。つまり、行が返されません。このシナリオはうまくいきます:

var result = connection.Query<int>( // case with rows
 "select DATEDIFF(day, GETUTCDATE(), @date)", new { date = DateTime.UtcNow.AddDays(20) })
 .SingleOrDefault();
result.IsEqualTo(20);

result = connection.Query<int>( // case without rows
    "select DATEDIFF(day, GETUTCDATE(), @date) where 1 = 0", new { date = DateTime.UtcNow.AddDays(20) })
    .SingleOrDefault();
result.IsEqualTo(0); // zero rows; default of int over zero rows is zero

どちらもうまく動作します。あなたがISNULL 「修正」しているということは、あなたが別のシナリオ、つまり「私は行を返しました」というシナリオを話していることを意味します。それが当てはまるので、あなたのコードが言っていることは、「nullを含むこの1つ以上の整数を取って、それを非nullのintとしてマップする」ことです。これは不可能であり、マッパーは投げても間違いありません例外。代わりに、あなたが望むものは次のとおりです。

int? result = connection.Query<int?>(...).SingleOrDefault();

今、行がある場合は、値をint?マッピングしていますint?その後、シングルまたはデフォルトを適用します。それをintとして、そしておそらく以下のようにします:

int result = connection.Query<int?>(...).SingleOrDefault() ?? 0;

「ゼロ行」と「ヌル結果」の違いを知る必要がある場合は、次のように提案します。

class NameMe {
    public int? Value {get;set;}
}
var row = connection.Query<NameMe>("select ... as [Value] ...", ...)
                    .SingleOrDefault();
if(row == null) {
   // no rows
} else if(row.Value == null) {
   // one row, null value
} else {
   // one row, non-null value
}

または類似のもの



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow