将datareader值转换为a到Nullable变量
我试图运行以下代码,但得到一个转换错误。 如何重写我的代码以实现相同的目标?
boolResult= (bool?)dataReader["BOOL_FLAG"] ?? true; intResult= (int?)dataReader["INT_VALUE"] ?? 0;
谢谢
在数据读取器上使用“IsDbNull”方法…例如:
bool? result = dataReader.IsDbNull(dataReader["Bool_Flag"]) ? null : (bool)dataReader["Bool_Flag"]
编辑
你需要做类似的事情:布尔? nullBoolean = null;
你有
bool? result = dataReader.IsDbNull(dataReader["Bool_Flag"]) ? nullBoolean : (bool)dataReader["Bool_Flag"]
考虑在一个函数中执行它。
这是我过去使用过的东西(你可以在.net 4中将其作为扩展方法):
public static T GetValueOrDefault(SqlDataReader dataReader, System.Enum columnIndex) { int index = Convert.ToInt32(columnIndex); return !dataReader.IsDBNull(index) ? (T)dataReader.GetValue(index) : default(T); }
编辑
作为扩展(未经过测试,但您明白了),并使用列名而不是索引:
public static T GetValueOrDefault(this SqlDataReader dataReader, string columnName) { return !dataReader.IsDBNull(dataReader[columnName]) ? (T)dataReader.GetValue(dataReader[columnName]) : default(T); }
用法:
bool? flag = dataReader.GetValueOrDefault("BOOL_COLUMN");
这里有一个可能有用的答案: https : //stackoverflow.com/a/3308515/1255900
您可以使用“as”关键字。 请注意评论中提到的警告。
nullableBoolResult = dataReader["BOOL_FLAG"] as bool?;
或者,如果您没有使用nullables,就像在原始post中一样:
boolResult = (dataReader["BOOL_FLAG"] as bool?) ?? 0;
bool? boolResult = null; int? intResult = null; if (dataReader.IsDBNull(reader.GetOrdinal("BOOL_FLAG")) == false) { boolResult = dataReader.GetBoolean(reader.GetOrdinal("BOOL_FLAG")); } else { boolResult = true; } if (dataReader.IsDBNull(reader.GetOrdinal("INT_VALUE")) == false) { intResult= dataReader.GetInt32(reader.GetOrdinal("INT_VALUE")); } else { intResult = 0; }
我确信我在互联网周围的某个地方找到了灵感,但我似乎无法找到原始来源。 无论如何,下面你找到一个实用程序类,它允许在DataReader上定义一个扩展方法,如下所示:
public static class DataReaderExtensions { public static TResult Get(this IDataReader reader, string name) { return reader.Get (reader.GetOrdinal(name)); } public static TResult Get (this IDataReader reader, int c) { return ConvertTo .From(reader[c]); } }
用法:
reader.Get("columnname")
要么
reader.Get(5)
这是启用实用程序类:
public static class ConvertTo { // 'Factory method delegate', set in the static constructor public static readonly Func ).GetMethod("ConvertNullableValueType", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new[] { type.GetGenericArguments()[0] })); } return ConvertValueType; } // ReSharper disable UnusedMember.Local // (used via reflection!) private static TElem? ConvertNullableValueType(object value) where TElem : struct { if (DBNull.Value == value) { return null; } return (TElem)value; } // ReSharper restore UnusedMember.Local private static T ConvertRefType(object value) { if (DBNull.Value != value) { return (T)value; } return default(T); } private static T ConvertValueType(object value) { if (DBNull.Value == value) { throw new NullReferenceException("Value is DbNull"); } return (T)value; } }
编辑:使用如下定义的IsNullableType()扩展方法:
public static bool IsNullableType(this Type type) { return (type.IsGenericType && !type.IsGenericTypeDefinition) && (typeof (Nullable<>) == type.GetGenericTypeDefinition()); }
这是我对扩展方法的镜头。 列名称语义,并在遇到null时回退到default(T)
。
public static class DbExtensions { public static T ReadAs(this IDataReader reader, string col) { object val = reader[col]; if (val is DBNull) { // Use the default if the column is null return default(T); } return (T)val; } }
这是示例用法。 请记住,尽管string
是一个引用类型,它仍然无法从DBNull
为null
。 int?
也是如此int?
。
public Facility Bind(IDataReader reader) { var x = new Facility(); x.ID = reader.ReadAs("ID"); x.Name = reader.ReadAs("Name"); x.Capacity = reader.ReadAs("Capacity"); x.Description = reader.ReadAs ("Description"); x.Address = reader.ReadAs ("Address"); return x; }
请记住,DBNull与null不同,因此您无法从一个转换为另一个。 正如另一张海报所说,你可以使用IsDBNull()方法检查DBNull。
试试这个版本。 它执行一些基本转换并管理默认值。