通用方法的优点是可以减少大量代码膨胀,但为每种数据类型制作自己的包装器可以让您灵活地进行自定义处理。与检索模式相比,您的数据库查询很可能会对性能产生显着的影响。
我建议您编写一组自己的扩展方法,而不是使用一种通用方法。将该方法扩展至IDataReader
给您带来的好处是无需在整个对象子类型上传播方法。我必须单独处理类型,因为各种连接器的行为不同,尤其是Guid
类型。也很难知道 datareader 是否读取了该值0
or DBNull
当你回来的时候0
对于这两种情况。假设您的表中有一个带有空值的枚举字段。为什么你希望它被读作第一个枚举?
只需致电:
dataReader.GetInt("columnName1")
dataReader.GetString("columnName3")
dataReader.GetFloat("columnName3")
以及方法:
public static int? GetInt(this IDataReader r, string columnName)
{
var i = r[columnName];
if (i.IsNull())
return null; //or your preferred value
return (int)i;
}
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null || obj == DBNull.Value;
}
同样,
public static string GetString(this IDataReader r, string columnName)
{
}
public static float GetFloat(this IDataReader r, string columnName)
{
}
如果您确实想要一个通用功能,您也可以拥有它。
public static T Get<T>(this IDataReader r, string columnName, T defaultValue = default(T))
{
var obj = r[columnName];
if (obj.IsNull())
return defaultValue;
return (T)obj;
}
所以称之为
dataReader.Get<int>(1); //if DBNull should be treated as 0
dataReader.Get<int?>(1); //if DBNull should be treated as null
dataReader.Get<int>(1, -1); //if DBNull should be treated as a custom value, say -1
也就是说,错误是因为您没有使用注释中指出的正确类型进行转换。我本可以选择内置的DBNull
检查,但我不会避免从读取器多次读取数据,受到这个奇怪的微优化案例的启发 https://stackoverflow.com/questions/221582/most-efficient-way-to-check-for-dbnull-and-then-assign-to-a-variable