12
(LocalVariable)ABC.string(Name) = (IDataReader)dataReader.GetString(0);

name值来自数据库。

如果这namenull在阅读时抛出异常,这里会发生什么?

我在这里手动做一些 if 条件。我不想编写手动条件来检查我的所有变量。

我现在正在做这样的事情..

String abc = dataReader.GetValue(0);
if (abc == null)
   //assigning null
else
   //assigning abc value

我们可以为此编写扩展方法吗?

4

5 回答 5

25

这里有几个扩展方法,它们可以很好地解决您对从数据读取器检索强类型值的所有担忧。如果值为 DbNull,则将返回该类型的默认值。如果string是类,null则返回 a。如果该字段是int,则将0返回。此外,如果您希望返回一个int?,例如来自可为空的 int 字段,null则将返回。

Kumar 案例的具体用法:

string abc = datareader.GetValueOrDefault<string>(0);

一般用法

var name = GetValueOrDefault<string>(reader, "Name");

或者

var name = reader.GetValueOrDefault<string>("Name");

或者

var name = reader.GetValueOrDefault<string>(0);

延期

public static class NullSafeGetter
{
   public static T GetValueOrDefault<T>(this IDataRecord row, string fieldName)
   {
       int ordinal = row.GetOrdinal(fieldName);
       return row.GetValueOrDefault<T>(ordinal);
   }

   public static T GetValueOrDefault<T>(this IDataRecord row, int ordinal)
   {
       return (T)(row.IsDBNull(ordinal) ? default(T) : row.GetValue(ordinal));
   }
}

来自http://skysanders.net/subtext/archive/2010/03/02/generic-nullsafe-idatarecord-field-getter.aspx

于 2010-04-09T19:17:04.767 回答
4

类似于@sky-sanders 的回答,但对转换不那么严格:

public static T Get<T>(this IDataRecord row, string fieldName)
{
    int ordinal = row.GetOrdinal(fieldName);
    return row.Get<T>(ordinal);
}

public static T Get<T>(this IDataRecord row, int ordinal)
{
    var value = row.IsDBNull(ordinal) ? default(T) : row.GetValue(ordinal);
    return (T)Convert.ChangeType(value, typeof(T));
}
于 2015-07-19T20:34:36.850 回答
2

我的解决方案是:

private static T GetValue<T>(object o) {
    if (typeof(DBNull) != o.GetType()) {
        return (T) o;
    }
    return default(T);
}

什么时候,Status = GetValue<string>(currentDataRow["status"])

于 2011-04-01T23:18:50.240 回答
2

结合顶级解决方案和建议,这是一个C# 6 箭头表达式版本,支持GetValue<T>GetValueOrDefault<T>带有可选的默认值参数。

public static class DataRecordExtensions {
    /// <summary>
    /// Generically extracts a field value by name from any IDataRecord as specified type. Will throw if DNE.
    /// </summary>
    public static T GetValue<T>(this IDataRecord row, string fieldName)
        => row.GetValue<T>(row.GetOrdinal(fieldName));

    /// <summary>
    /// Generically extracts a field value by ordinal from any IDataRecord as specified type. Will throw if DNE.
    /// </summary>
    public static T GetValue<T>(this IDataRecord row, int ordinal)
        => (T)row.GetValue(ordinal);

    /// <summary>
    /// Generically extracts a field value by name from any IDataRecord as specified type. Will return default generic types value if DNE.
    /// </summary>
    public static T GetValueOrDefault<T>(this IDataRecord row, string fieldName, T defaultValue = default(T))
        => row.GetValueOrDefault<T>(row.GetOrdinal(fieldName), defaultValue);

    /// <summary>
    /// Generically extracts a field value by ordinal from any IDataRecord as specified type. Will return default generic types value if DNE.
    /// </summary>
    public static T GetValueOrDefault<T>(this IDataRecord row, int ordinal, T defaultValue = default(T))
        => (T)(row.IsDBNull(ordinal) ? defaultValue : row.GetValue(ordinal));
}
于 2016-03-15T18:05:55.213 回答
0

我会使用这样的东西:

string abc = (IDataReader)datareader.GetValue(0) ?? "Default";
于 2010-04-09T18:31:10.877 回答