我们如何从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)
);
答案 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;
}
}