C#:从存储过程填充组合框仅显示第一项

C#: Populating combobox from stored procedure only displays first item

我试图通过执行存储过程在初始化时填充组合框。当我 运行 我的数据库上的程序时,出现 3 行:

但是一旦我在我的代码中执行该过程:

public partial class AddInstitutionStart : Window
    {
        public AddInstitutionStart()
        {
            InitializeComponent();
            ComboBoxInstitutionCategory.Items.Add(FillCombo.fillInstCategory());
        }
    }

    public static class FillCombo
    {
        public static string fillInstCategory()
        {
            string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
            SqlConnection Connect = null;
            SqlCommand Command;
            using (Connect = new SqlConnection(connstr))
            {
                Connect.Open();
                using (Command = new SqlCommand("[dbo].[spMetadataTb_GetCategory]", Connect))
                {
                    Command.CommandType = CommandType.StoredProcedure;
                    SqlDataReader dr = Command.ExecuteReader();
                    while (dr.Read())
                    {
                        string categoryInst = dr.GetString(0);
                        return categoryInst;
                    }
                }

                Command.Dispose();
                Connect.Close();
                return "-2";
            }
        }
    }

只显示第一行:

我已经使用相同的逻辑来填充另一个组合框(不是在初始化时)并且它工作完美并显示多个项目。知道我在这里可能做错了什么吗?

像这样的东西...只处理你的 reader。

public static List<string> fillInstCategory()
{
    string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
    SqlConnection Connect = null;
    SqlCommand Command;
    List<string> categories = new List<string>();
    using (Connect = new SqlConnection(connstr))
    {
        Connect.Open();
        using (Command = new SqlCommand("[dbo].[spMetadataTb_GetCategory]", Connect))
        {
            Command.CommandType = CommandType.StoredProcedure;
            SqlDataReader dr = Command.ExecuteReader();
            while (dr.Read())
            {
                string categoryInst = dr.GetString(0);
                categories.Add(categoryInst);
            }
        }

        Command.Dispose();
        Connect.Close();
        return categories;
    }
}

对此有很多可能的解决方案,但请忘记 static!

第一名:

return 来自另一个答案的列表,像这样使用它:

public partial class AddInstitutionStart : Window
{
    public AddInstitutionStart()
    {
        InitializeComponent();
        foreach(string cat in new FillCombo().fillInstCategory())
            ComboBoxInstitutionCategory.Items.Add(cat);
    }
}

或者,如果 AddRange 存在:

public partial class AddInstitutionStart : Window
{
    public AddInstitutionStart()
    {
        InitializeComponent();
        ComboBoxInstitutionCategory.Items.AddRange(new FillCombo().fillInstCategory());
    }
}

此解决方案首先填充 fillInstCategory() 中的列表,然后通过 foreach 或 addrange 填充您的 combobox

第二名:

使其成为可枚举函数(使用方法同上):

您的代码只有 2 处更改,第 1 处:

public IEnumerable<string> GetInstCategory()
{
    ...
}

然后扩展 return 单词 yield:

        while (dr.Read())
            yield return dr.GetString(0);

这会在读取每个数据后立即填充组合框(不是一次,当读取所有数据时与解决方案1一样),因为yield 导致在 Items.AddWhile(dr.Read()) 代码部分之间来回跳转。

第三:

注入方法(或 lambda 表达式):

您的代码只有 2 处更改,第 1 处:

public void GetInstCategory(Action<string> Injection)
{
    ...
}

然后:

        while (dr.Read())
            Injection(dr.GetString(0));

像这样使用它:

public partial class AddInstitutionStart : Window
{
    public AddInstitutionStart()
    {
        InitializeComponent();
        new FillCombo().fillInstCategory(ComboBoxInstitutionCategory.Items.Add)) //note there is no "(" and ")" after Add, so the addition doesnt happen, just the function was passed to "fillInstCategory" to use it whenever necessary.
    }
}

这与解决方案 2 的组合框填充方式相同:读取 1 个数据,然后将 1 添加到组合框,然后再次读取...

希望你能从中学到一些东西。