从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;
}