Foreach不断循环

时间:2015-07-09 12:35:55

标签: c# .net sqlite visual-studio-2008 windows-mobile-6.5

所以我有这个项目需要从数据库打印数据。 我用一个简单的foreach循环来做到这一点:

public void LoadDatabase()
    {
        _connection.Open();
        _dataAdapter.Fill(_dataTable);

        try
        {
            foreach (DataRow row in _dataTable.Rows)
            {
                Program.AnimalInfo.Info_ID_ListBox.Items.Add(row["Animal_ID"].ToString());
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Failed to LoadDatabase()" + ex.Message);
        }
        _connection.Close();     
    }

问题在于它会循环2次到6次,这意味着它至少会打印两次。 所以目前我的数据库包含Animal_Id的id:1和id:2。 现在我进入我的列表框(1,2,1,2)或更多,具体取决于循环的数量。我不知道为什么会这样,以及如何解决这个问题。所以所有的帮助都将受到高度赞赏

ps:如果需要更多代码或信息,请告诉我。

pss:这是适用于在Visual Studio 2008中使用.net 3.5构建的Windows Mobile 6.5设备。也使用sqlite(不是最新版本)

编辑:经过一些测试,看起来我的其他2个foreach循环在这个项目中有同样的问题。

编辑:所以有了你的家伙的帮助我能够解决它。

public void GetData()
    {
        try
        {
            SQLiteConnection Connection = new SQLiteConnection(@"Data Source = \Program Files\Mobile\Resources\Database\PPP_DB");

            Connection.Open();

            SQLiteCommand Command = new SQLiteCommand(Query, Connection);
            Command.ExecuteNonQuery();

            Data_Adapter = new SQLiteDataAdapter("SELECT * FROM Animal_Info", Connection);
            Data_Set.Reset();
            Data_Adapter.Fill(Data_Set);
            Data_Table = Data_Set.Tables[0];

            Program.AnimalInfo.Info_ID_ListBox.Items.Clear();

            foreach (DataRow row in Data_Table.Rows)
            {
                if (row.RowState != DataRowState.Deleted)
                {
                    Program.AnimalInfo.Info_ID_ListBox.Items.Add(row["Animal_ID"].ToString());
                }
            }
            Connection.Close();
            Program.AnimalInfo.Refresh();
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }  
    }

所以它似乎与某个地方的DataTable搞混了,这让它多次循环。 ps:我试图用像Databound这样的东西来设置所有项目,但是对我来说并没有真正有效,这就是我仍然这样做的原因。

4 个答案:

答案 0 :(得分:3)

在函数顶部添加以下两行。

Program.AnimalInfo.Info_ID_ListBox.Items.Clear();
_dataTable.Clear();

这将确保您不会将任何行数据加倍。

答案 1 :(得分:0)

假设" Animal_ID"没有唯一约束。数据库中的字段(你不回答我的评论),检查项目是否重复:

if (!Program.AnimalInfo.Info_ID_ListBox.Items.Contains(row["Animal_ID"].ToString())
  Program.AnimalInfo.Info_ID_ListBox.Items.Add(row["Animal_ID"].ToString());

答案 2 :(得分:0)

首先,LoadDatabase()应该返回一个DataTable(或DataSet),这使得LoadDatabase()函数对其他数据请求很有用,而且你永远不需要使用' for循环'将项添加到ListBox。你可以将ListBox直接绑定到源代码......像这样的事情应该这样做

listBox1.DataSource = _dataTable;
listBox1.ValueMember = "Animal_ID";
listBox1.DisplayMember = "Animal_ID";

这里有一些使用SqlDataReader和SqlDataAdapter的例子http://gsidev.somee.com/#2&2AD97ECBE2AE41D08191F6E4C773D8A9&cs

答案 3 :(得分:0)

此处不需要独特的约束。但可能必须清除listbox.Items集合。

可能你是(或系统,取决于代码的位置,例如在绘图事件处理程序中)调用'LoadDatabase()'函数两次!

只需在_dataAdapter.fill()中放置一个断点,然后按F11让应用程序运行,然后右键单击_dataTable以检查其内容。

虽然您可以明确设置ListBox的数据源,但这不是必需的,并且可能会导致您目前不知道的其他副作用。在让系统在后台解压缩之前,可以先用简单的代码开始。

试试:

public void LoadDatabase()
{
    _connection.Open();
    _dataAdapter.Fill(_dataTable);
    Program.AnimalInfo.Info_ID_ListBox.Items.Clear();
    try
    {
        foreach (DataRow row in _dataTable.Rows)
        {
            Program.AnimalInfo.Info_ID_ListBox.Items.Add(row["Animal_ID"].ToString());
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Failed to LoadDatabase()" + ex.Message);
    }
    _connection.Close();     
}