我们假设我们有一个开放的SqlConnection
并执行一个任意查询,从而产生一个包含一列 Foo 的表,其中包含整数。
要读取这些整数,我注意到有两种方法可以访问列中的值:
using (var reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
// access value directly either by column name or index
int i = (int)reader["Foo"];
int j = (int)reader[0];
// access value by using GetOrdinal
int k = reader.GetInt32(reader.GetOrdinal("Foo"));
}
}
}
两种方法当然都会产生相同的值。我正在使用第一种方法,因为我似乎更容易使用列名直接访问值而不是使用它来获取其索引,然后使用该索引来访问该值。
但我对这个问题很陌生,那么这里的最佳做法是什么?目前的惯例?绩效方面的差异?
答案 0 :(得分:1)
所有方法都是正确的,但reader["Foo"]
和reader[0]
正在使用定义的重载索引器。它总是容易/可读,并建议在索引器中使用列名而不是使用索引。不确定它们之间的性能差异。
int i = (int)reader["Foo"];
int j = (int)reader[0];
答案 1 :(得分:1)
类似的东西:
using (var reader = command.ExecuteReader()) {
// if (reader.HasRows) is redundant
// do not repeat this in the loop
int k_index = reader.GetOrdinal("Foo");
while (reader.Read()) {
// reader["Foo"] is not necessary int;
// better practice is to convert since reader["Foo"] could be, say, Oracle Number
int i = Convert.ToInt32(reader["Foo"]);
// usually, reader[123] (instead of reader["MyField"]) syntax looks ugly, but
// it may happen that, say, "id" is always the first field in the query -
// so reader[0] syntax is reasonable
int j = Convert.ToInt32(reader[0]);
// what if reader[index] is declared as Int64 but contains Int32 values - convert
int k = Convert.ToInt32(reader[k_index]);
}
}
答案 2 :(得分:1)
使用反射器,您可以在内部看到索引器[]
与调用方法
public override object this[int i]
{
get
{
return this.GetValue(i);
}
}
public override object this[string name]
{
get
{
return this.GetValue(this.GetOrdinal(name));
}
}
所以实际差异是。如果您知道位置并关心性能,请使用方法的int版本。
int j = (int)reader[0];//direct array access for some column
int j = reader.GetInt32(0);
如果您不知道该位置或更喜欢可读性,请使用字符串版本
//must first goto hash table and waist time looking for column index
int j = (int)reader["price"]; //but at least we know the meaning of the column
int j = reader.GetInt32(reader.GetOrdinal("price"));
int j = (int)reader.GetValue(reader.GetOrdinal("price"));
并最终确定GetInt32
和GetValue
之间的差异只是GetInt32
为您进行类型验证和投射,因此如果您知道数据类型会让您的生活更轻松。
PS。通过名称查找列索引的性能损失通常是可以忽略的..但是......不应该被忽略,我有一个项目,其中GetOrdinal
是最被称为函数的函数之一数十万次总结到几秒钟,我可以通过使用整数来避免,现在我遇到了瓶颈,我无法重写应用程序。
答案 3 :(得分:0)
您将经常使用SqlDataReader
,因此请尽可能简化,指定列名称:
int i = (int)reader["Foo"];