C# foreach只返回第一个id,并复制其余id
我正在运行嵌套的foreach,首先我想获取所有id,然后我想为每个id填充datagridview,但它只返回第一个id六次。我的表只有六个数据行。使用断点运行诊断,DataTable dt0拥有所有id,但DataTable dt2只有第一个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();
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();
}