2012-08-07 31 views
1

我試圖從SQL數據庫中的數據(從1和表4列)加載到一個列表,有這個迄今爲止錯誤讀取的IDataReader幾次

List<string> FNameList = (from IDataRecord r in myReader 
          select (string)r["FirstName"]).ToList(); 

List<string> LNameList = (from IDataRecord r in myReader 
          select (string)r["LastName"]).ToList(); 

List<string> EmailList = (from IDataRecord r in myReader 
          select (string)r["Email"]).ToList(); 

List<string> PhoneList = (from IDataRecord r in myReader 
          select (string)r["PhoneNumber"]).ToList(); 

現在,我使用的數據庫有三行數據,所以每一行的長度應該是3.但是隻有第一行返回長度爲三;其他人的長度爲0.更奇怪的是,如果我將第一個註釋掉,第二個會起作用,但其他人不會。同樣與第三和第四。

這很難解釋,因爲我不能提供數據庫進行測試,所以我想知道上面是否有任何明顯的內容,或者如果這是將列數據加載到數組/列表格式的錯誤方法。

+3

假設myReader是SqlDataReader。然後這只是前進,第一次使用後不能再次重新啓動 – Steve 2012-08-07 09:12:10

+0

@Steve,這是問題的答案 – Habib 2012-08-07 09:13:30

回答

3

我假設你有一個類似於Select擴展方法對此:

public static IEnumerable<T> Select<T>(this IDataReader reader, Func<IDataRecord, T> selector) 
{ 
    while(reader.Read()) 
     yield return selector(reader); 
} 

因此,當讀者被枚舉時,它在可用數據的末尾,再次讀取數據的唯一方法是重新發出查詢。因此,您需要一次提取所有字段:

var records = (from IDataRecord r in myReader 
       select new 
       { 
        FirstName = (string)r["FirstName"], 
        LastName = (string)r["LastName"], 
        Email = (string)r["Email"], 
        PhoneNumber = (string)r["PhoneNumber"] 
       }).ToList(); 
+0

謝謝,這個伎倆 – OSer 2012-08-07 09:48:33

2

在第一個查詢後,您的讀者正在前進到最後一條記錄。您需要提取所有行,然後構建您的列表:

var records = (from IDataRecord r in myReader select r).ToArray(); 

List<string> LNameList = (from IDataRecord r in records 
         select (string)r["LastName"]).ToList(); 
// Keep the last row for all fields 
+0

這將無法正常工作......它會返回最後一個記錄3次(除非'Select'複製數據記錄在產生它們之前,但似乎不太可能) – 2012-08-07 09:17:17

+0

ToArray方法在內存集合中創建.NET。 – 2012-08-07 09:19:17

+0

是的,但是如果'Select'像我認爲的那樣實現,它實際上總是返回與IDataRecord相同的實例;在枚舉結束時,IDataRecord包含最後一條記錄的數據。您需要在*前進到下一條記錄之前提取每條記錄的內容*。 – 2012-08-07 09:23:37

2

myReader是一個SqlDataReader。 SqlDataReader provides a way of reading a forward-only stream of rows from a SQL Server database。 第一次使用後不能再次重新啓動。

您需要在一個循環中讀取所有數據,然後根據需要構建您的列表
但是,我不明白爲什麼要以這種方式劃分信息。

+0

謝謝Steve,你100%正確。我對數據管理非常陌生,所以我只是想找點工作。托馬斯的答案爲我工作,所以謝謝大家! – OSer 2012-08-07 09:52:03

1

首先聲明一個POCO持有的屬性:

class Person 
{ 
    ... 
} 

然後一個輔助方法:

private static IEnumerable<Person> ReadReader(IDataReader reader) 
{ 
    using (reader) 
    { 
     while (reader.Read()) 
     { 
      yield return new Person 
      { 
       FirstName = (string)reader["FirstName"], 
       LastName = (string)reader["LastName"], 
       Email = (string)reader["Email"], 
       PhoneNumber = (string)reader["PhoneNumber"] 
      } 
     } 
    } 
} 

用法:

List<Person> list = RaderReader(command.ExecuteReader()).ToList();