我尝试运行以下代码,但出现了强制类型转换错误。如何重写我的代码以达到相同的效果?
boolResult= (bool?)dataReader["BOOL_FLAG"] ?? true;
intResult= (int?)dataReader["INT_VALUE"] ?? 0;
感谢
bool? result = dataReader.IsDbNull(dataReader["Bool_Flag"]) ? null : (bool)dataReader["Bool_Flag"]
编辑
您需要执行类似于以下操作:
bool? nullBoolean = null;
然后您会拥有
bool? result = dataReader.IsDbNull(dataReader["Bool_Flag"]) ? nullBoolean : (bool)dataReader["Bool_Flag"]
? (bool?)null : (bool)dataReader["Bool_Flag"]
。 - Winston Smithpublic static T GetValueOrDefault<T>(SqlDataReader dataReader, System.Enum columnIndex)
{
int index = Convert.ToInt32(columnIndex);
return !dataReader.IsDBNull(index) ? (T)dataReader.GetValue(index) : default(T);
}
编辑
作为一个扩展(未经测试,但您会明白),并使用列名而不是索引:
public static T GetValueOrDefault<T>(this SqlDataReader dataReader, string columnName)
{
return !dataReader.IsDBNull(dataReader[columnName]) ? (T)dataReader.GetValue(dataReader[columnName]) : default(T);
}
用法:
bool? flag = dataReader.GetValueOrDefault("BOOL_COLUMN");
IsDBNull()
只接受一个整数参数,所以你需要像这样调用:dataReader.IsDBNull(dataReader.GetOrdinal(columnName))
。 - Ishmael Smyrnow这里有一个可能会有帮助的答案: https://dev59.com/rXI-5IYBdhLWcg3wm5lG#3308515
你可以使用"as"关键字。请注意评论中提到的警告。
nullableBoolResult = dataReader["BOOL_FLAG"] as bool?;
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;
}
public static T GetValueOrDefault <T> (this SqlDataReader reader, string column) {
var isDbNull = reader[column] == DBNull.Value;
return !isDbNull ? (T) reader[column] : default (T);
}
我确定我在互联网上找到了这个灵感,但现在似乎找不到原始来源了。无论如何,下面您会发现一个实用类,它允许在DataReader上定义扩展方法,就像这样:
public static class DataReaderExtensions
{
public static TResult Get<TResult>(this IDataReader reader, string name)
{
return reader.Get<TResult>(reader.GetOrdinal(name));
}
public static TResult Get<TResult>(this IDataReader reader, int c)
{
return ConvertTo<TResult>.From(reader[c]);
}
}
使用方法:
reader.Get<bool?>("columnname")
或者
reader.Get<int?>(5)
这是启用实用类:
public static class ConvertTo<T>
{
// 'Factory method delegate', set in the static constructor
public static readonly Func<object, T> From;
static ConvertTo()
{
From = Create(typeof(T));
}
private static Func<object, T> Create(Type type)
{
if (!type.IsValueType) { return ConvertRefType; }
if (type.IsNullableType())
{
return (Func<object, T>)Delegate.CreateDelegate(typeof(Func<object, T>), typeof(ConvertTo<T>).GetMethod("ConvertNullableValueType", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new[] { type.GetGenericArguments()[0] }));
}
return ConvertValueType;
}
// ReSharper disable UnusedMember.Local
// (used via reflection!)
private static TElem? ConvertNullableValueType<TElem>(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());
}
default(T)
。public static class DbExtensions
{
public static T ReadAs<T>(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?
也是如此。public Facility Bind(IDataReader reader)
{
var x = new Facility();
x.ID = reader.ReadAs<Guid>("ID");
x.Name = reader.ReadAs<string>("Name");
x.Capacity = reader.ReadAs<int?>("Capacity");
x.Description = reader.ReadAs<string>("Description");
x.Address = reader.ReadAs<string>("Address");
return x;
}
请记住,DBNull和null不是同一回事,因此您不能从一个转换为另一个。正如其他帖子所说,您可以使用IsDBNull()方法来检查DBNull。