将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 From; static ConvertTo() { From = Create(typeof(T)); } private static Func Create(Type type) { if (!type.IsValueType) { return ConvertRefType; } if (type.IsNullableType()) { return (Func)Delegate.CreateDelegate(typeof(Func), typeof(ConvertTo).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是一个引用类型,它仍然无法从DBNullnullint?也是如此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。

试试这个版本。 它执行一些基本转换并管理默认值。