我正在尝试运行以下代码,但会出现转换错误。 我怎样才能重写我的代码以实现相同的目标呢?
boolResult= (bool?)dataReader["BOOL_FLAG"] ?? true;
intResult= (int?)dataReader["INT_VALUE"] ?? 0;
由于
答案 0 :(得分:14)
在数据阅读器上使用“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"]
答案 1 :(得分:10)
考虑在一个函数中执行它。
这是我过去使用过的东西(你可以在.net 4中将其作为扩展方法):
public 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");
答案 2 :(得分:3)
这里有一个可能有帮助的答案: https://stackoverflow.com/a/3308515/1255900
您可以使用“as”关键字。请注意评论中提到的警告。
nullableBoolResult = dataReader["BOOL_FLAG"] as bool?;
或者,如果您没有使用nullables,就像在原帖中一样:
boolResult = (dataReader["BOOL_FLAG"] as bool?) ?? 0;
答案 3 :(得分:2)
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;
}
答案 4 :(得分:1)
我确信我在互联网周围的某个地方找到了灵感,但我似乎无法找到原始来源。无论如何,下面你找到一个实用程序类,它允许在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());
}
答案 5 :(得分:1)
这是我对扩展方法的镜头。列名称语义,当遇到null时,它会回退到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
是引用类型,但它仍然无法从null
转换为DBNull
。 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;
}
答案 6 :(得分:1)
使用扩展方法:
public static T GetValueOrDefault <T> (this SqlDataReader reader, string column) {
var isDbNull = reader[column] == DBNull.Value;
return !isDbNull ? (T) reader[column] : default (T);
}
答案 7 :(得分:0)
请记住,DBNull与null不同,因此您无法从一个转换为另一个。正如另一张海报所说,您可以使用IsDBNull()方法检查DBNull。
答案 8 :(得分:-2)
试用this版本。它执行一些基本转换并管理默认值。