2010-10-05 42 views
1
string connectionString = ConfigurationManager.AppSettings["AllRttpDBConnectionString"]; 
MySqlConnection connection = new MySqlConnection(connectionString); 
MySqlCommand command = connection.CreateCommand(); 

command.CommandText = "Select * from test where ServiceName like 'T%' " ; 

try 
{ 
    connection.Open(); 
} 
catch (Exception e) 
{ 
    Console.WriteLine(e.ToString()); 
} 

try 
{ 
    MySqlDataReader reader; 
    reader = command.ExecuteReader(); 

    while (reader.Read()) 
    { 
    Player.Name = reader["Name"].ToString(); 
    Player.Number = Convert.ToInt32(reader["Number"].ToString()); 

    //push to list 
    PlayerList.Add(Player); 
    } 

    connection.Close(); 
} 
catch (Exception e) 
{ 
    connection.Close(); 
    logger.Info(e.ToString()); 
} 

上面是我用來從數據庫中讀取多行到列表中的代碼。但是,我所有的列表項都具有完全相同的數據(數據庫的最後一行)。從數據庫讀取多行 - 我哪裏錯了?

我知道它可能是一個非常簡單,愚蠢的錯誤,但我只是看不到它。

回答

6

它看起來像你一遍又一遍地將相同的對象再次,改變值什麼讀fromt當前行。您需要使用:

Player player = new Player() 
player.Name = reader["Name"].ToString(); 
player.Number = Convert.ToInt32(reader["Number"].ToString()); 

//push to list 
PlayerList.Add(player); 

然後將其添加到集合中。

+0

哦......我以爲它會覆蓋循環的每一次迭代的值。猜猜我錯了。讓我試試你的解決方案。 – xbonez 2010-10-05 20:12:50

+0

它每次迭代都會覆蓋這些值,問題在於您一遍又一遍地添加相同的實例,因爲在您讀取期間更新值時它是相同的實例,因此列表中的每個元素都會更新,因此列表中的每個元素都會更新對象的相同實例。 – Daniel 2010-10-05 20:16:00

+0

謝謝。這工作! – xbonez 2010-10-05 20:16:07

4

它看起來像你不斷修改一個Player實例。

爲了解決這個問題,爲每個記錄創建一個新的實例:

while (reader.Read()) 
{ 
    // I'm guessing about the type here 
    Player player = new Player(); 
    player.Name = reader["Name"].ToString(); 
    player.Number = Convert.ToInt32(reader["Number"].ToString()); 

    //push to list 
    PlayerList.Add(player); 
} 
2

所以發生了什麼事情,你每次將它添加到列表中時都沒有做出新的Player

當您將項目添加到列表中時,您的代碼應該看起來像這樣。

PlayerClass NewPlayer = new PlayerClass; 
NewPlayer.Name = reader["Name"].ToString(); 
NewPlayer.Number = Convert.ToInt32(reader["Number"].ToString()); 

//push to list 
PlayerList.Add(NewPlayer); 
2

讓我建議你在你的代碼略有改善:

public IEnumerable<Player> GetPlayers() 
{ 
    string connectionString = ConfigurationManager.AppSettings["AllRttpDBConnectionString"]; 
    using (var conn = new MySqlConnection(connectionString)) 
    using (var cmd = conn.CreateCommand()) 
    { 
     conn.Open(); 
     cmd.CommandText = "SELECT Name, Number FROM test WHERE ServiceName LIKE 'T%';"; 
     using (var reader = cmd.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       yield return new Player 
       { 
        Name = reader.GetString(0), 
        Number = reader.GetInt32(1) 
       }; 
      } 
     } 
    } 
} 

而且當你需要創建一個列表:

List<Player> playersList = GetPlayers().ToList(); 

您還需要確保妥善處置所有可支配的資源都在我的例子中。

+0

謝謝。我明白你所做的。我將把使用的代碼塊合併到我的代碼中。 – xbonez 2010-10-05 20:16:34

+0

不僅使用塊,也使用數據讀取器上的適當方法避免了類型轉換,以及通過返回'IEnumerable '而不是一個避免將所有結果集全部載入內存的延遲加載的可能性不需要。 – 2010-10-05 20:17:43