C# - 按索引的 SQLDataReader 与 SQLDataReader.GetOrdinal(ColumnName)
C# - SQLDataReader by Index vs. SQLDataReader.GetOrdinal(ColumnName)
一个被认为是更好的标准?一个比另一个快吗?或者,主要是偏好? GetOrdinal 很好,因为您可以自己调用列名,而不必担心计算 SQL 中字段的索引,但我想知道是否有使用一个优于另一个的好处。
按索引阅读:
while (reader.Read())
{
Column1 = reader.GetValue(0).ToString().Trim();
Column2 = reader.GetValue(1).ToString().Trim();
}
Reader.GetOrdinal:
while (reader.Read())
{
data.Column1 = reader.GetValue(reader.GetOrdinal("COLUMN1")).ToString();
data.Column2 = reader.GetValue(reader.GetOrdinal("COLUMN2")).ToString();
data.Column3 = reader.GetDateTime(reader.GetOrdinal("COLUMN3"));
}
reader.GetOrdinal(string) 将获得列序号,给定列名
我们可以从 SqlDataReader 中看到 GetOrdinal
源代码,它将 return 来自 _fieldNameLookup.GetOrdinal
的索引(_fieldNameLookup
字段是 FieldNameLookup
class)
_fieldNames
is a hashtable stores the index, match via case-sensitive
override public int GetOrdinal(string name) {
SqlStatistics statistics = null;
try {
statistics = SqlStatistics.StartTimer(Statistics);
if (null == _fieldNameLookup) {
CheckMetaDataIsReady();
_fieldNameLookup = new FieldNameLookup(this, _defaultLCID);
}
return _fieldNameLookup.GetOrdinal(name); // MDAC 71470
}
finally {
SqlStatistics.StopTimer(statistics);
}
}
我们可以从FieldNameLookup
class.
中看到源代码GetOrdinal
方法
public int GetOrdinal(string fieldName) { // V1.2.3300
if (null == fieldName) {
throw ADP.ArgumentNull("fieldName");
}
int index = IndexOf(fieldName);
if (-1 == index) {
throw ADP.IndexOutOfRange(fieldName);
}
return index;
}
public int IndexOf(string fieldName) { // V1.2.3300
if (null == _fieldNameLookup) {
GenerateLookup();
}
int index;
object value = _fieldNameLookup[fieldName];
if (null != value) {
// via case sensitive search, first match with lowest ordinal matches
index = (int) value;
}
else {
// via case insensitive search, first match with lowest ordinal matches
index = LinearIndexOf(fieldName, CompareOptions.IgnoreCase);
if (-1 == index) {
// do the slow search now (kana, width insensitive comparison)
index = LinearIndexOf(fieldName, ADP.compareOptions);
}
}
return index;
}
Is one quicker than the other?
如果您已经知道列存在索引号 reader.GetValue(0)
将比 reader.GetValue(reader.GetOrdinal("COLUMN1"))
更快,因为它不会导致资源从 reader.GetOrdinal
方法获取列索引。
Is one considered better standard?
没有比较标准,因为reader.GetValue(0)
和reader.GetValue(reader.GetOrdinal("COLUMN1"))
做的是一样的,跟之前的回答一样
reader.GetValue(reader.GetOrdinal("COLUMN1"))
比 reader.GetValue(0)
更好读,因为列名比索引更好。
我总是使用 returns 字典的函数,其中列名作为键,索引作为值,比如那个:
public IDictionary<string, int> GetColumnNames(ref SqlDataReader reader) {
IDictionary<string, int> dict = new Dictionary<string, int>();
if (reader == null)
return dict;
int columns = reader.FieldCount;
for (int i = 0; i < columns; i++) {
dict[reader.GetName(i)] = i;
}
return dict;
}
然后您可以随时调用创建新对象:
var cols = GetColumnNames(ref r);
while (r.Read())
var value = r.GetInt32(cols["SOME_COLUMN"]);
我真的不知道它是否更快,但对我有用。
此外,适用于定义的常量列名。
一个被认为是更好的标准?一个比另一个快吗?或者,主要是偏好? GetOrdinal 很好,因为您可以自己调用列名,而不必担心计算 SQL 中字段的索引,但我想知道是否有使用一个优于另一个的好处。
按索引阅读:
while (reader.Read())
{
Column1 = reader.GetValue(0).ToString().Trim();
Column2 = reader.GetValue(1).ToString().Trim();
}
Reader.GetOrdinal:
while (reader.Read())
{
data.Column1 = reader.GetValue(reader.GetOrdinal("COLUMN1")).ToString();
data.Column2 = reader.GetValue(reader.GetOrdinal("COLUMN2")).ToString();
data.Column3 = reader.GetDateTime(reader.GetOrdinal("COLUMN3"));
}
reader.GetOrdinal(string) 将获得列序号,给定列名
我们可以从 SqlDataReader 中看到 GetOrdinal
源代码,它将 return 来自 _fieldNameLookup.GetOrdinal
的索引(_fieldNameLookup
字段是 FieldNameLookup
class)
_fieldNames
is a hashtable stores the index, match via case-sensitive
override public int GetOrdinal(string name) {
SqlStatistics statistics = null;
try {
statistics = SqlStatistics.StartTimer(Statistics);
if (null == _fieldNameLookup) {
CheckMetaDataIsReady();
_fieldNameLookup = new FieldNameLookup(this, _defaultLCID);
}
return _fieldNameLookup.GetOrdinal(name); // MDAC 71470
}
finally {
SqlStatistics.StopTimer(statistics);
}
}
我们可以从FieldNameLookup
class.
GetOrdinal
方法
public int GetOrdinal(string fieldName) { // V1.2.3300
if (null == fieldName) {
throw ADP.ArgumentNull("fieldName");
}
int index = IndexOf(fieldName);
if (-1 == index) {
throw ADP.IndexOutOfRange(fieldName);
}
return index;
}
public int IndexOf(string fieldName) { // V1.2.3300
if (null == _fieldNameLookup) {
GenerateLookup();
}
int index;
object value = _fieldNameLookup[fieldName];
if (null != value) {
// via case sensitive search, first match with lowest ordinal matches
index = (int) value;
}
else {
// via case insensitive search, first match with lowest ordinal matches
index = LinearIndexOf(fieldName, CompareOptions.IgnoreCase);
if (-1 == index) {
// do the slow search now (kana, width insensitive comparison)
index = LinearIndexOf(fieldName, ADP.compareOptions);
}
}
return index;
}
Is one quicker than the other?
如果您已经知道列存在索引号 reader.GetValue(0)
将比 reader.GetValue(reader.GetOrdinal("COLUMN1"))
更快,因为它不会导致资源从 reader.GetOrdinal
方法获取列索引。
Is one considered better standard?
没有比较标准,因为reader.GetValue(0)
和reader.GetValue(reader.GetOrdinal("COLUMN1"))
做的是一样的,跟之前的回答一样
reader.GetValue(reader.GetOrdinal("COLUMN1"))
比 reader.GetValue(0)
更好读,因为列名比索引更好。
我总是使用 returns 字典的函数,其中列名作为键,索引作为值,比如那个:
public IDictionary<string, int> GetColumnNames(ref SqlDataReader reader) {
IDictionary<string, int> dict = new Dictionary<string, int>();
if (reader == null)
return dict;
int columns = reader.FieldCount;
for (int i = 0; i < columns; i++) {
dict[reader.GetName(i)] = i;
}
return dict;
}
然后您可以随时调用创建新对象:
var cols = GetColumnNames(ref r);
while (r.Read())
var value = r.GetInt32(cols["SOME_COLUMN"]);
我真的不知道它是否更快,但对我有用。 此外,适用于定义的常量列名。