在ado.net?

时间:2015-09-04 06:21:59

标签: c# generics reflection ado.net

SqlDataReader获取价值的最佳方法是什么?

我编写了一个实用程序函数,用于从基础数据类型中按列名检索值,任何人都可以建议改进它。

我认为低效的是分别为每种类型提供实现,这将使许多类型处于未处理状态。

我的代码可以为我没有处理的类型提供编译类型错误吗?我考虑使用通用约束,但在我的情况下它们并没有帮助。

public static T GetValue<T>(SqlDataReader reader, string columnName,T defaultValue=default(T))
{
    int ordinal;

    // checking whether column name exist in reader result set
    try
    {
        ordinal = reader.GetOrdinal(columnName);
    }
    catch (IndexOutOfRangeException columnException)
    {
       var innerexception = new IndexOutOfRangeException(String.Format("Column name does not exist in specified SqlDataReader, {0}", columnException.Message), columnException);

       throw innerexception;
   }
   catch (Exception e)
   {
       throw e;
   }

   // Defining Types and their corresponding functions to be called.
   var typeDictionary = new Dictionary<Type, Func<T>>
            {
                {typeof(Int16), () => (T)Convert.ChangeType(reader.GetInt16(ordinal),typeof(T))},
                {typeof(Int32), () => (T)Convert.ChangeType(reader.GetInt32(ordinal),typeof(T))},
                {typeof(Int64), () => (T)Convert.ChangeType(reader.GetInt64(ordinal),typeof(T))},
                {typeof(String), () => (T)Convert.ChangeType(reader.GetString(ordinal),typeof(T))},
                {typeof(Boolean), () => (T)Convert.ChangeType(reader.GetBoolean(ordinal),typeof(T))},
                {typeof(Byte), () => (T)Convert.ChangeType(reader.GetByte(ordinal),typeof(T))},
                {typeof(DateTime), () => (T)Convert.ChangeType(reader.GetDateTime(ordinal),typeof(T))},
                {typeof(Char), () => (T)Convert.ChangeType(reader.GetChar(ordinal),typeof(T))},
                {typeof(Decimal), () => (T)Convert.ChangeType(reader.GetDecimal(ordinal),typeof(T))},
                {typeof(Double), () => (T)Convert.ChangeType(reader.GetDouble(ordinal),typeof(T))}
            };

   Type providedType = typeof (T);

   // Handling nullable types, If programmer wants to pass null value as default he should pass struct type with '?'.
   if (providedType.IsGenericType && 
       providedType.GetGenericTypeDefinition() == typeof (Nullable<>))
   {
       providedType = Nullable.GetUnderlyingType(providedType);
   }

   if (typeDictionary[providedType] == null)
   {
       throw new ArgumentException("Not Supported Type");
   }

   var resultedValue = reader.IsDBNull(ordinal) ? defaultValue : typeDictionary[typeof (T)]();

   return resultedValue;
}

0 个答案:

没有答案