0

在使用诸如 System.Data.Odbc 或 System.Data.OracleClient 之类的命名空间时,各种数据读取器方法通常需要为函数提供与列对应的整数(例如OracleDataReader.GetInt32)。

我的问题是,使用这些函数的最佳方法是什么,以使代码具有相当的自我记录性。现在,在我看来,有三个选择,即:

// Option One - Just provide the integer value
string myString = oraData.GetString[0];

// Option Two - Provide the integer value using a constant
string myString = oraData.GetString[FIELD_NAME];

// Option Three - Provide the column name and use System.Convert to return the correct value
string myString = Convert.ToString(oraData["Field_Name"]);

这些技术中的每一种似乎都有自己的优点和缺点,我很想知道其他人的想法,或者是否有更好的方法来做到这一点。

4

3 回答 3

2

我一直这样做:

int columnIndex = dataReader.GetOrdinal("field");

if (!dataReader.IsDBNull(columnIndex))
    String myString = dataReader.GetString(columnIndex);

当我试图获得一个不在读者中的字段时,这个想法GetOrdinal将会失败。IndexOutOfRangeException我想要这个异常,因为它很快告诉我我的代码和我的数据库之间不匹配。

GetOrdinal比将序数本身硬编码为幻数要脆弱得多。

于 2009-01-13T14:52:02.033 回答
1

我通常使用选项 3。我喜欢它,因为如果底层查询改变了列顺序,它仍然可以工作,并且它会在那里显示你所要求的名称,而不是一些幻数。

但是,我使用了很多 VB.Net,所以这Convert.ToString()部分可以隐式完成。C# 类型可能有不同的偏好。

此外,使用字段名称而不是列序号会受到非常小的惩罚。我通常认为这是合理的,但根据您的应用程序,您可能需要考虑到这一点。

于 2009-01-13T14:50:53.267 回答
1

我同意 Andrew Hare 的观点,此外,我已将功能包含在简化操作的重载扩展方法中:

public static string GetStringByName(this OracleDataReader reader, 
                                     string columnName, 
                                     string defaultValue)
{
   string result = defaultValue;
   int columnIndex = reader.GetOrdinal(columnName);
   if(!reader.IsDbNull(columnName)
   {
      result = (string) reader.GetString(columnIndex);
   }
   return result;
}

无论如何,只是一个对我帮助很大的重构。

于 2009-01-13T15:38:25.650 回答