C# 使用datagridview C windows应用程序插入数据

C# 使用datagridview C windows应用程序插入数据,c#,datagridview,C#,Datagridview,上面的代码正确插入数据,但gridview自动生成新行,这会产生错误您可以在foreach行之后添加此检查 try { foreach (DataGridViewRow row in dataGridView1.Rows) { string constring = @"Data Source=ZEE-PC\SQLEXPRESS;Initial Catalog=MyBill;Integrated Se

上面的代码正确插入数据,但gridview自动生成新行,这会产生错误

您可以在foreach行之后添加此检查

 try
        {
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                string constring = @"Data Source=ZEE-PC\SQLEXPRESS;Initial Catalog=MyBill;Integrated Security=True;Pooling=False";
                using (SqlConnection con = new SqlConnection(constring))
                {
                    using (SqlCommand cmd = new SqlCommand("INSERT INTO stock VALUES(@productname, @packing,@totalquantity,@rate,@expry,@dealername)", con))
                    {
                        cmd.Parameters.AddWithValue("@productname", row.Cells["pname"].Value);
                        cmd.Parameters.AddWithValue("@packing", row.Cells["packing"].Value);
                        cmd.Parameters.AddWithValue("@totalquantity", row.Cells["quantity"].Value);
                        cmd.Parameters.AddWithValue("@rate", row.Cells["rate"].Value);
                        cmd.Parameters.AddWithValue("@expry", row.Cells["exp"].Value);
                        cmd.Parameters.AddWithValue("@dealername", row.Cells["dname"].Value);

                        con.Open();
                        cmd.ExecuteNonQuery();
                        con.Close();
                    }
                }
            }
        }
        catch(SqlException ex) {
            MessageBox.Show(ex.ToString());
        }
        MessageBox.Show("Records inserted.");
    }
不过,我建议您重构一点代码。基本上,您是在每个循环中重建连接、命令和所有参数。相反,您可以在启动循环之前构建连接、命令和参数。在循环内部,仅更改参数值并执行查询

foreach (DataGridViewRow row in dataGridView1.Rows)
{
    if(!row.IsNewRow)
    {
        ....
    }
}

您可以在插入前检查行是否为空。还请注意,所有插入只有一个连接:

using (SqlConnection con = new SqlConnection(constring))
using (SqlCommand cmd = new SqlCommand("INSERT INTO stock VALUES(@productname, @packing,@totalquantity,@rate,@expry,@dealername)", con))
{
    cmd.Parameters.Add("@productname", SqlDbType.NVarChar);
    .... all the other parameters follow....
    con.Open();
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        if(!row.IsNewRow)
        {
            cmd.Parameter["@productname"].Value = row.Cells["pname"].Value);
            ....
            .... set all other parameters with the row values
            ....
            cmd.ExecuteNonQuery();
        }
    }
}
编辑:按照Steve的建议,最好检查IsNewRow属性

如果该行是中的最后一行,则DataGridViewRow.IsNewRow返回true DataGridView,用于输入新行数据; 否则,错误


代码回顾:不要禁用池,不要在循环中重新创建连接和命令。也许可以使用ifrow.IsNewRow continue对其进行一点改进;而不是把你的整个代码块都放在if里。为什么?这里面有一些隐藏的优势?不是隐藏的。通过反转if语句,可以通过减少缩进来提高代码的可读性。而且,没有人会怀疑}在所有代码的末尾做了什么。当人们提供关于提高代码可读性的建议时,这是一个常见的建议。例如,参见CodeReviews,我不同意这一点。我更喜欢减少最少的语句,比如break和continue,但不确定可读性,因为我从不在for/while/if中放太多代码行,如果在该块中只调用一次,我更喜欢添加子或函数。归根结底,这些只是偏好。
string constring = @"Data Source=ZEE-PC\SQLEXPRESS;Initial Catalog=MyBill;Integrated Security=True;Pooling=False";
using (SqlConnection con = new SqlConnection(constring))
{
    con.Open();

    foreach (var row in dataGridView1.Rows)
    {
        var productName = row.Cells["pname"].Value;
        if (string.IsNullOrEmpty(productName))
            continue;

        using (SqlCommand cmd = new SqlCommand("INSERT INTO stock VALUES(@productname, @packing,@totalquantity,@rate,@expry,@dealername)", con))
        {
            cmd.Parameters.AddWithValue("@productname", );
            cmd.Parameters.AddWithValue("@packing", row.Cells["packing"].Value);
            cmd.Parameters.AddWithValue("@totalquantity", row.Cells["quantity"].Value);
            cmd.Parameters.AddWithValue("@rate", row.Cells["rate"].Value);
            cmd.Parameters.AddWithValue("@expry", row.Cells["exp"].Value);
            cmd.Parameters.AddWithValue("@dealername", row.Cells["dname"].Value);

            cmd.ExecuteNonQuery();
        }
    }
}