得到一个int?来自db使用DbDataReader

时间:2010-10-26 08:20:53

标签: c# .net

有没有聪明的方法来缩短这种淫秽物?它有效,但它不可读......

int? myVal = r.IsDBNull(r.GetOrdinal("colName")) ? (int?)null : r.GetInt32(r.GetOrdinal("colName"));

谢谢:)

3 个答案:

答案 0 :(得分:6)

您可以将该代码放入DbDataReader的扩展方法中(或者在它实现的IDataReader接口上更好)。这样,看起来很可怕的代码隐藏在一个看起来更漂亮的GetNullableInt32()调用之后:

public static class IDataReaderExtensions
{
    public static int? GetNullableInt32(this IDataReader r, string columnName)
    {
        int? myVal = r.IsDBNull(r.GetOrdinal(columnName)) 
                        ? (int?) null : 
                        r.GetInt32(r.GetOrdinal(columnName));
        return myVal;
    }
}

然后您可以使用以下方式调用它:

IDataReader reader = ...;
int? value = reader.GetNullableInt32("colName");

正如伊恩指出的那样,最好只召唤r.GetOrdinal()一次:

public static class IDataReaderExtensions
{
    public static int? GetNullableInt32(this IDataReader r, string columnName)
    {
        int ordinal = r.GetOrdinal(columnName);
        int? myVal = r.IsDBNull(ordinal) 
                        ? (int?) null : 
                        r.GetInt32(ordinal);
        return myVal;
    }
}

答案 1 :(得分:2)

除了Adrian's answer之外,您还可以制作一个通用的扩展方法来满足所有类型:

int? myVal = r.GetValue<int?>("colName");

// ...

public static class DataReaderExtensions
{
    public static T GetValue<T>(this IDataReader dr, string columnName)
    {
        return dr.GetValue<T>(dr.GetOrdinal(columnName));
    }

    public static T GetValue<T>(this IDataReader dr, int columnOrdinal)
    {
        // does the column contain null?
        if (dr.IsDBNull(columnOrdinal))
        {
            // is T either a ref type or a nullable value type?
            Type t = typeof(T);
            if (!t.IsValueType || (Nullable.GetUnderlyingType(t) != null))
            {
                // return null
                return default(T);
            }
        }

        // get the column value, cast it as T and return it
        // this will throw if the value isn't convertible/unboxable to T
        return (T)dr.GetValue(columnOrdinal);
   }
}

答案 2 :(得分:0)

不是真的。我经常把这个代码放在一个方法中并调用它。这种方法可能最终会出现在一个普通的“助手”类中,或者我认为甚至是一种扩展方法(尽管我个人并不喜欢这些方法,因为他们很难发现其他人)。