C# 当由数据库填充时,Combobox将使值加倍

C# 当由数据库填充时,Combobox将使值加倍,c#,winforms,combobox,C#,Winforms,Combobox,我使用WinC窗体和SQL Server作为我的数据库 在my Combobox_Leave事件中,它将使用上一个的文本值填充其他Combobox 这是我的Combobox\u Leave事件之一,与其他Combobox类似 其中,例如,cmbPItem.Text是制动片 它将查询近675行 编辑:至于凯文的建议。此代码仅用于品牌组合框,但仍显示重复值 private void cmbProd_Enter(object sender, EventArgs e) { itemValue(c

我使用WinC窗体和SQL Server作为我的数据库

在my Combobox_Leave事件中,它将使用上一个的文本值填充其他Combobox

这是我的Combobox\u Leave事件之一,与其他Combobox类似

其中,例如,cmbPItem.Text是制动片

它将查询近675行

编辑:至于凯文的建议。此代码仅用于品牌组合框,但仍显示重复值

private void cmbProd_Enter(object sender, EventArgs e) {
    itemValue(cmbPItem.Text); }

private void itemValue(string sitem) {
    getBrand(sitem); }

private void getBrand(string sitem) {
    using (SqlCommand cmd = new SqlCommand(@"SELECT DISTINCT [Brand] FROM [dbo].[products] WHERE Item = @Item"))
    {
        cmd.Parameters.Add(new SqlParameter("Item", sitem));
        populateBrand(cmbPBrand, cmd);
    } }

private void populateBrand(ComboBox cmb, SqlCommand cmd) {
    using (SqlConnection conn = new SqlConnection(@"Server=" + ip + "," + port + "; Database=records; User ID=" + sqlid + "; Password=" + sqlpass + ""))
    {
        using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
        {
            cmd.Connection = conn;
            DataTable dt = new DataTable();
            sda.Fill(dt);
            if (dt.Rows.Count != 0)
            {
                cmb.Items.Clear();
                for (int b = 0; b < dt.Rows.Count; b++)
                {
                    cmb.Items.Add(dt.Rows[b][0].ToString());
                }
            }
            conn.Close();
        }
    } }

我建议从稍微不同的角度来解决这个问题

首先,您肯定应该考虑将这些查询更改为参数化。正如我所评论的,任何时候将原始输入直接放入SQL语句中,都会打开SQL注入攻击的大门。即使不是基于用户的输入,这仍然是一个坏习惯。执行SQL参数化并不难——它只是额外的一行代码

下一步:重构代码。如果我理解正确,您的代码如下所示:

Event X
{
    13 or so lines to update Combo Box #1
    13 or so lines to update Combo Box #2
    13 or so lines to update Combo Box #3
    13 or so lines to update Combo Box #4
}
Event Y
{
    13 or so lines to update Combo Box #1
    13 or so lines to update Combo Box #2
    13 or so lines to update Combo Box #3
    13 or so lines to update Combo Box #4
}
Event Z
{
    13 or so lines to update Combo Box #1
    13 or so lines to update Combo Box #2
    13 or so lines to update Combo Box #3
    13 or so lines to update Combo Box #4
}
Event ... etc
在谷歌上搜索一下,玩转单一责任原则SRP——它将帮助您编写更干净、更易于调试的代码

什么时候说的,什么时候做的?然后,您就有了一个很好的方法来确定问题是什么:在UpdateBrandCombo函数中放入一些调试行,这是目前唯一一个更新品牌组合框的地方,您有一个问题,这些事件中的任何一个都可能在更新组合框,而您实际上没有任何好的方法来确定它在做什么

比如:

Event X
{
    UpdateCombosWithSearch(cmbPItem.Text);
}
// ... later on ...
private void UpdateCombosWithSearch(string searchTerm)
{
    UpdateBrandCombo(searchTerm);
    UpdateMfgCombo(searchTerm);
    UpdateCarCombo(searchTerm);
}
private void UpdateBrandCombo(string searchTerm)
{
        SqlCommand sqlCmd = new SqlCommand("select distinct car from dbo.products where Item like @item");
        sqlCmd.Parameters.Add(new SqlParameter("item", searchTerm));
        SetComboBoxUsingQuery(cmbPBrand, sqlCmd);
}
private void SetComboBoxUsingQuery(ComboBox cbx, SqlCommand sqlCmd)
{
    cbx.Items.Clear();
    // code to get a DataTable from the sqlCmd
    // code to read the DataTable and add items to cbx
}
System.Diagnostics.Debug.WriteLine("Event logged by " + (new System.Diagnostics.StackTrace()).ToString());
看到美了吗?你没有重复的代码。您的所有事件都有一行:UpdateCombosWithSearch。UpdateCombosWithSearch只需在需要更新的每个组合框上调用更新。这些函数中的每一个都只是生成一个SQL命令,并在其中传递要更新的框。唯一有SQL代码的函数是SetComboBoxUsingQuery函数

现在您可以添加如下内容:

Event X
{
    UpdateCombosWithSearch(cmbPItem.Text);
}
// ... later on ...
private void UpdateCombosWithSearch(string searchTerm)
{
    UpdateBrandCombo(searchTerm);
    UpdateMfgCombo(searchTerm);
    UpdateCarCombo(searchTerm);
}
private void UpdateBrandCombo(string searchTerm)
{
        SqlCommand sqlCmd = new SqlCommand("select distinct car from dbo.products where Item like @item");
        sqlCmd.Parameters.Add(new SqlParameter("item", searchTerm));
        SetComboBoxUsingQuery(cmbPBrand, sqlCmd);
}
private void SetComboBoxUsingQuery(ComboBox cbx, SqlCommand sqlCmd)
{
    cbx.Items.Clear();
    // code to get a DataTable from the sqlCmd
    // code to read the DataTable and add items to cbx
}
System.Diagnostics.Debug.WriteLine("Event logged by " + (new System.Diagnostics.StackTrace()).ToString());

。。。到其中一个函数-这样您就可以知道在哪里/何时/如何调用您的更新代码。

我看不出您编写的代码中有任何问题,请编写完整的代码。当我填充组合框时,这是完整的代码。它是在填充时发生的吗?或者什么时候触发事件?编辑为什么不使用一个PS根据您的条件获取所有行?当我尝试在代码中的SqlDataAdapter.FillDataTable或sda.Filldt处添加断点时。在If条件下,下一步将返回到事件的开始,使用SqlConnection。。。然后我会再看一遍整个街区。编辑:你说的PS是什么意思?对不起,我不太熟悉。强制性要求:不要这样做。您正在向SQL注入攻击敞开大门。使用参数化查询,传入要搜索的条件。任何时候直接将输入放入SQL语句,都会打开注入攻击的大门。我明天会这样做,并会回来改进。我对您共享的模板做了类似的操作。它解决了我的问题。我观察到的是,当我在单击下拉箭头之前在组合框内单击/输入时,它不会显示重复的值。但是当我首先单击下拉箭头时,它会显示重复的值。我通过添加if解决了这个问题!cmbPBrand.Items.Containsdt.Rows[b][0]。ToString在我的FOR循环中。谢谢你给我更多的信息,刚开始几个月,对这个发展中的东西了解很少,这将在未来帮助我。没问题-祝你好运。还有,你应该看看:罗伯特·鲍伯·马丁叔叔的《干净的代码》。这本书帮助我成为了一名更好的开发人员,可能是编程领域最有影响力的书之一。它超越了SRP和许多其他编程概念来生成干净的代码。