11

Sql Data Reader から整数の null 値を読み取る方法

SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read() == true)
{
    mb.Id = (int)reader["Id"];
    mb.Mem_NA = (string)reader["Mem_NA"];
    mb.Mem_ResAdd4 = reader["Mem_ResAdd4"] == System.DBNull.Value ? null : (string)reader["Mem_ResAdd4"];
    //
   mb.Mem_ResPin = reader["Mem_ResPin"] as  int? ?? default(int);
  // shows the error "Object cannot be cast from DBNull to other types."
 }

mb.Mem_ResPin がリーダーから読み取れない

 CREATE TABLE [dbo].[Mem_Basic] (
[Id]          INT           IDENTITY (1, 1) NOT NULL,
[Mem_NA]      VARCHAR (100) NOT NULL,
[Mem_ResAdd4] VARCHAR (100) NULL,
[Mem_ResPin]  INT           NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
4

8 に答える 8

14

前の行で行ったように、変換するだけです

mb.Mem_ResAdd4 = reader["Mem_ResAdd4"] == System.DBNull.Value ? null : (string)reader["Mem_ResAdd4"];
//
    mb.Mem_ResPin = reader["Mem_ResPin"]== System.DBNull.Value ? default(int):(int)reader["Mem_ResPin"]
于 2013-08-30T10:34:03.060 に答える
9

すべての DB キャストに汎用拡張メソッドを使用します。

public static T? DbCast<T>(this object dbValue)
        where T : struct
    {
        if (dbValue == null)
        {
            return null;
        }
        if (dbValue is System.DBNull)
        {
            return null;
        }
        T? value = dbValue as T?;
        if (value != null)
        {
            return value;
        }
        var conv = dbValue as IConvertible;
        if (conv != null)
        {
            value = (T)conv.ToType(typeof(T), CultureInfo.InvariantCulture);
        }
        return value;
    }

これまでに遭遇したすべての状況を処理しようとします。必要に応じて条件を調整します。

使用法:

int? value = reader["Mem_ResAdd4"].DbCast<int>()
于 2013-08-30T10:39:37.070 に答える
5

IsDBNullたとえば拡張メソッドとして単純なラッパーを作成し、内部をチェックします。

public static int SafeGetInt(this SqlDataReader reader, string colName)
{
    var colIndex = reader.GetOrdinal(colName);
    return !reader.IsDBNull(colIndex) ? reader.GetInt32(colIndex) : default(int);
}

利用方法:

var result = reader.SafeGetInt(colName);
于 2013-08-30T10:39:20.473 に答える
2

ここにはいくつかのアプローチがあります。残念ながら、DBNullこれは面倒です。API は、値である可能性がある をreader[name]返します。そのため、( ) を確認して処理する必要があります。もう 1 つのアプローチはAPI を使用することですが、お気づきのように、名前ではなく序数(列インデックス) が必要です。どちらの場合でも、役立つユーティリティ メソッドなどを追加できます。objectDBNull.Valueisreader.IsDBNull(ordinal)

static object Read(IDataReader reader, string name)
{
    var val = reader[name];
    return val is DBNull ? (object)null : val;
}

次に(例):

mb.Mem_ResPin = (int?)Read(reader, "Mem_ResPin")

ただし、繰り返しになりますが、「dapper」などのツールを使用すると、これがはるかに簡単になる場合があります。単一で、ヌル、 、およびその他のさまざまなシナリオQuery<T>(tsql, args).SingleOrDefault()を含む、これらすべてに対処できます。Nullable<T>

于 2013-08-30T10:38:11.280 に答える
1

比較は に対してDBNullです。

var resPin = reader["Mem_ResPin"];
if(!Convert.IsDBNull(resPin))
  mb.Mem_ResPin = resPin as int?;
else
  mb.Mem_ResPin = new Nullable<int>();
于 2013-08-30T10:34:08.063 に答える