C# foreach只返回第一个id,并复制其余id

C# foreach只返回第一个id,并复制其余id,c#,.net,sql-server,C#,.net,Sql Server,我正在运行嵌套的foreach,首先我想获取所有id,然后我想为每个id填充datagridview,但它只返回第一个id六次。我的表只有六个数据行。使用断点运行诊断,DataTable dt0拥有所有id,但DataTable dt2只有第一个id。其他变量也一样 int id = 0; int price = 0; int qty = 0; private void button1_Click(object sender, EventArgs e) { con.Open();

我正在运行嵌套的foreach,首先我想获取所有id,然后我想为每个id填充datagridview,但它只返回第一个id六次。我的表只有六个数据行。使用断点运行诊断,DataTable dt0拥有所有id,但DataTable dt2只有第一个id。其他变量也一样

int id = 0;
int price = 0;
int qty = 0;


private void button1_Click(object sender, EventArgs e)
{
    con.Open();
    string sql = "SELECT id FROM tbl_price ";
    SqlCommand cmd0 = new SqlCommand(sql, con);
    SqlDataAdapter dAdapter0 = new SqlDataAdapter(cmd0);
    DataTable dt0 = new DataTable();

    dAdapter0.Fill(dt0);
    if (dt0.Rows.Count > 0)
    {
        foreach (DataRow dr in dt0.Rows)
        {
            SqlCommand cmd2 = new SqlCommand("SELECT P.id, P.price, Q.qty FROM tbl_price P INNER JOIN tbl_qty Q ON P.id=Q.id WHERE P.id='" + dt0.Rows[0]["id"] + "'  ", con);
            SqlDataAdapter dAdapter2 = new SqlDataAdapter(cmd2);
            DataTable dt2 = new DataTable();
            dAdapter2.Fill(dt2);

            id = Convert.ToInt32(dt2.Rows[0]["id"]);
            price = Convert.ToInt32(dt2.Rows[0]["price"]);
            qty = Convert.ToInt32(dt2.Rows[0]["qty"]);

            int n = dataGridView1.Rows.Add();
            dataGridView1.Rows[n].Cells["dgid"].Value = id;
            dataGridView1.Rows[n].Cells["dgprice"].Value = price;
            dataGridView1.Rows[n].Cells["dgqty"].Value = qty;

        }
    }
    con.Close();
}
//下面是我在Datagridview中的结果

   id   qty price
    1   100 10  
    1   100 10  
    1   100 10  
    1   100 10  
    1   100 10  
    1   100 10  

在不知道SQL中数据的结构的情况下,有点难以判断,但我对这一行表示怀疑 SqlCommand cmd2=new SqlCommandSELECT P.id,P.price,Q.qty FROM tbl_price P internal JOIN tbl_qty Q ON P.id=Q.id,其中P.id='+dt0.Rows[0][id]+',con

这对我意味着,尽管在行中循环,第二个查询始终使用dt0.rows的第一个元素

我将尝试用dr[id]替换dt0.Rows[0][id]

给您的第一行仍然相同。如果要循环遍历所有行,则需要一些迭代器


因此,您最好使用for而不是foreach,特别是因为您不使用DataRow dr。

我假设您的查询从tbl\U qty返回每个id 1行。如果不是这样,这可能需要改变

一些注意事项:

您不需要为此函数运行2个查询。 虽然字符串连接可以为SQL注入打开窗口,但您可以删除它 此函数中使用1查询的连接。 使用时不需要对行>0进行测试 弗雷奇。 将连接工作包装在一个try中,然后在finally中关闭连接,以确保在出现故障时关闭连接,这也是一种很好的做法。 将代码简化如下可能会有所帮助:

        con.Open();
        try
        {
            string sql = "SELECT P.id, P.price, Q.qty FROM tbl_price P INNER JOIN tbl_qty Q ON P.id=Q.id";
            SqlCommand cmd0 = new SqlCommand(sql, con);
            SqlDataAdapter dAdapter0 = new SqlDataAdapter(cmd0);
            DataTable dt0 = new DataTable();
            dAdapter0.Fill(dt0);

            foreach (DataRow dr in dt0.Rows)
            {
                id = Convert.ToInt32(dr["id"]);
                price = Convert.ToInt32(dr["price"]);
                qty = Convert.ToInt32(dr["qty"]);

                int n = dataGridView1.Rows.Add();
                dataGridView1.Rows[n].Cells["dgid"].Value = id;
                dataGridView1.Rows[n].Cells["dgprice"].Value = price;
                dataGridView1.Rows[n].Cells["dgqty"].Value = qty;
            }
        }
        finally
        {
            con.Close();
        }
有关设置dataGridView行值和进一步缩短代码的不同方法,请参见答案


缩短代码的一个原因是为了减少一些复杂性,使其更易于调试。

嵌套的foreach在哪里?为什么不只进行一次连接?此处不需要任何嵌套。将dt0.Rows[0][id]替换为dr[id]有效。阿洛特
        con.Open();
        try
        {
            string sql = "SELECT P.id, P.price, Q.qty FROM tbl_price P INNER JOIN tbl_qty Q ON P.id=Q.id";
            SqlCommand cmd0 = new SqlCommand(sql, con);
            SqlDataAdapter dAdapter0 = new SqlDataAdapter(cmd0);
            DataTable dt0 = new DataTable();
            dAdapter0.Fill(dt0);

            foreach (DataRow dr in dt0.Rows)
            {
                id = Convert.ToInt32(dr["id"]);
                price = Convert.ToInt32(dr["price"]);
                qty = Convert.ToInt32(dr["qty"]);

                int n = dataGridView1.Rows.Add();
                dataGridView1.Rows[n].Cells["dgid"].Value = id;
                dataGridView1.Rows[n].Cells["dgprice"].Value = price;
                dataGridView1.Rows[n].Cells["dgqty"].Value = qty;
            }
        }
        finally
        {
            con.Close();
        }