2009-05-28 62 views
1

假設我正在調用一個查詢「SELECT name,city,country FROM People」。一旦我執行了我的SqlDataReader,列的排列順序與我的sql查詢中的順序相同嗎?SqlDataReader列常規

換句話說,我可以依靠下面的代碼將始終正常工作:

SqlConnection connection = new SqlConnection(MyConnectionString); 
SqlCommand command = new SqlCommand(); 
command.Connection = connection; 
command.CommandText = "SELECT [name], [city], [country] WHERE [id] = @id"; 

try 
{ 
    connection.Open(); 
    SqlDataReader reader = command.ExecuteReader(System.Data.CommandBehavior.SingleRow); 

    if (reader.Read()) 
    { 
     // Read values. 
     name = reader[0].ToString(); 
     city = reader[1].ToString(); 
     country = reader[2].ToString(); 
    } 
} 
catch (Exception) 
{ 
    throw; 
} 
finally 
{ 
    connection.Close(); 
} 

也多少表現我輸,如果我使用的列名,而不是序數(讀者[「名稱」])?

是否有任何官方的微軟文檔描述SqlDataReader中列排序的行爲?

回答

5

是的,但你也可以使用SqlDataReader.GetName(ordinal)和SqlDataReader.GetOrdinal(name)。

至於性能,我認爲這可能是非常微不足道的說,開銷說,檢索下一行數據。

+0

嗨喬希。感謝您的及時答覆。那麼這種行爲是否有保證,我應該依賴它還是使用列名更好? PS - 至於GetOrdinal,我不認爲它對我有用,因爲我只檢索一行。 – niaher 2009-05-28 04:56:26

5

我完全同意Josh--這些字段的位置確實如您在SQL查詢文本中指定的那樣。

但我仍然喜歡使用列名稱,因爲它更健壯。例如。如果你需要添加一個字段到你的SQL查詢怎麼辦?

command.CommandText = "SELECT [name], [jobtitle], [city], [country] WHERE [id] = @id"; 

現在突然間,你不得不重寫所有的代碼來改變位置....

我通常做的是通過數據讀取器返回的所有行列舉外循環是什麼確定的位置我感興趣的每個領域:

int namePosition = reader.GetOrdinal("name"); 
int cityPosition = reader.GetOrdinal("city"); 

然後我在處理數據的循環中使用這些位置以快速訪問各個字段。這樣,您只需確定一次職位,但是您在循環數據時使用了職位 - 兩全其美! :-)

馬克

4

這個例子是最易維護和最容易閱讀:

int? quantity = reader.Get<int?>("Quantity"); 
Guid token = reader.Get<Guid>("Token"); 

它依賴於我創建了下面的擴展方法。它執行數據庫空值檢查,當找不到字段時提供信息錯誤消息,並且當列重新對齊時不會中斷。

internal static T Get<T>(this SqlDataReader reader, string fieldName) 
{ 
    int ordinal; 
    try 
    { 
     ordinal = reader.GetOrdinal(fieldName); 
    } 
    catch (IndexOutOfRangeException) 
    { 
     throw new IndexOutOfRangeException(string.Format("Field name '{0}' not found.", fieldName)); 
    } 

    return !reader.IsDBNull(ordinal) ? (T)reader.GetValue(ordinal) : default(T); 
}