当使用诸如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"]);
这些技巧中的每一种似乎都有自己的优点和缺点,我很想知道别人的想法,或者是否有更好的方法去做。
答案 0 :(得分:2)
我一直这样做:
int columnIndex = dataReader.GetOrdinal("field");
if (!dataReader.IsDBNull(columnIndex))
String myString = dataReader.GetString(columnIndex);
当我尝试获取一个不在读者中的字段时,GetOrdinal
将失败IndexOutOfRangeException
的想法。我想要这个例外,因为它很快告诉我,我的代码和我的数据库之间存在不匹配。
同样GetOrdinal
比将序数本身硬编码为幻数要脆得多。
答案 1 :(得分:1)
我通常使用选项3.我喜欢它,因为如果基础查询改变了列顺序,它仍然可以工作,它会显示你在那里要求的名称,而不是一些幻数。
但是,我使用了很多VB.Net,因此Convert.ToString()
部分可以隐式完成。 C#类型可能有不同的偏好。
此外,使用字段名称而不是列序数会受到很小的惩罚。我通常认为这是合理的,但根据您的应用程序,您可能需要考虑到这一点。
答案 2 :(得分: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;
}
无论如何,只是一个极大帮助我的重构。