读者可以为Nulllable的整数值

时间:2013-08-30 10:24:17

标签: c# sql

我们如何从Sql Data Reader中读取整数空值

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)
);

8 个答案:

答案 0 :(得分:9)

只需转换它,就像你在前一行中所做的那样

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"]

答案 1 :(得分:5)

我对所有数据集强制转换使用通用扩展方法:

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>()

答案 2 :(得分:4)

写一个简单的包装器,例如作为扩展方法并检查内部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);

答案 3 :(得分:2)

这里有一些方法。不幸的是,DBNull让这令人烦恼 - reader[name] API返回object可能是您的值,或者可能是DBNull.Value - 因此您必须检查({1}} {1}})并处理它。另一种方法是使用is API,但正如您将注意到的那样:需要序数(列索引)而不是名称。在任何一种情况下,您都可以添加实用程序方法之类的东西来帮助:

reader.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") 将处理所有这些,包括空值,Query<T>(tsql, args).SingleOrDefault()和一系列其他方案。

答案 4 :(得分:2)

也许试试这个延伸:

public static class Helper
{
    public static T GetSafe<T>(this SqlDataReader reader, string name)
    {
        var value = reader[name];
        return value == DBNull.Value ? default(T) : (T) value;
    }
}

并使用如下:

        if (reader.Read())
        {
            Mb mb = new Mb();
            mb.Id = reader.GetSafe<int>("Id");
            mb.Mem_NA = reader.GetSafe<string>("Mem_NA");
            mb.Mem_ResAdd4 = reader.GetSafe<string>("Mem_ResAdd4");

            mb.Mem_ResPin = reader.GetSafe<int>("ResPin");
        }

答案 5 :(得分:2)

您可以使用SqlDataReader.GetSqlInt32来处理Nullable<int>

SqlInt32 resPin = reader.GetSqlInt32(reader.GetOrdinal("Mem_ResPin"));
mb.Mem_ResPin = resPin.IsNull ? (int?) null : resPin.Value;

答案 6 :(得分:1)

比较是针对DBNull

var resPin = reader["Mem_ResPin"];
if(!Convert.IsDBNull(resPin))
  mb.Mem_ResPin = resPin as int?;
else
  mb.Mem_ResPin = new Nullable<int>();

答案 7 :(得分:0)

public static class SqlDataReaderExtensions
{
    public static T Value<T>(this SqlDataReader reader, string name, T defaultValue = default)
    {
        var val = reader[name];

        if (val == DBNull.Value)
            return defaultValue;

        return (T)val;
    }
}