Вывод трех строк одного столбца из базы данных в C#

Делаю тест на C# с использованием Windows Forms. Использую элемент SqlDataReader для чтения всех данных из таблицы базы данных при помощи запроса. Когда получаю данные и вывожу их, то вижу, что в одну переменную заносятся все вопросы, привязанные к определенному ID (По логике так и должно быть). На форме с вопросами у меня есть элемент TabControl с тремя страницами, на каждой из которой есть label для вывода вопроса и radiobutton'ы/textbox'ы для ввода ответа. По ходу работы выяснилось, что при выводе вопросов в label'ы выводится только последний вопрос, который был встречен в таблице с привязкой к указанному ID. Возник вопрос, могу ли я как-то "разделить" поток данных для вывода без изменения запроса, чтобы в одну переменную для вывода я мог записать один вопрос из таблицы, во вторую - второй вопрос и так далее?

 string connectionString = @"Data Source=LAPTOP-EL5SC6G8\SQLEXPRESS;Initial Catalog=KP_DataBase;Integrated Security=True";
 string sql = $"SELECT * FROM Questions WHERE ID_theme = '{Test.Theme_ID}'";
 using (SqlConnection sqlConnection = new SqlConnection(connectionString))
 {
     sqlConnection.Open();
     SqlCommand command = new SqlCommand(sql, sqlConnection);
     SqlDataReader reader = command.ExecuteReader();
     if (reader.HasRows)
     {
         while (reader.Read())
        {
            object Question_Title = reader["Question_title"].ToString();
            MessageBox.Show(Question_Title.ToString());           
            label1.Text = Question_Title.ToString();                            
        }
     } 
     reader.Close();
 }

Таблица, из которой беру данные введите сюда описание изображения

Форма, на которой вывожу вопросы с вариантами ответов введите сюда описание изображения


Ответы (1 шт):

Автор решения: aepot

Если по-простому, то как-то так.

StringBuilder sb = new StringBuilder();
while (reader.Read())
{
    string Question_Title = reader["Question_title"].ToString();
    sb.AppendLine(Question_Title);                            
}
label1.Text = sb.ToSting();

Или можно в список прочитать

List<string> list = new List<string>();
while (reader.Read())
{
    string Question_Title = reader["Question_title"].ToString();
    list.Add(Question_Title);                            
}

Как читать базу

Создайте класс

public class QuestionData
{
    public int Id { get; }
    public string Title { get; }
    public List<string> Answers { get; }
    public int ThemeId { get; }
    public string InputType { get; }

    public QuestionData(int id, string title, List<string> answers, int themeId, string inputType)
    {
        Id = id;
        Title = title;
        Answers = answers;
        ThemeId = themeId;
        InputType = inputType;
    }
}

Создайте глобальный список этих вопросов

public List<QuestionData> Questions { get; private set; }

И вот так читайте

Questions = new List<QuestionData>();
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
    sqlConnection.Open();
    SqlCommand command = new SqlCommand(sql, sqlConnection);
    SqlDataReader reader = command.ExecuteReader();
    if (reader.HasRows)
    {
        while (reader.Read())
        {
            int id = reader.GetInt32(0);
            string title = reader.GetString(1);
            List<string> answers = new List<string>();
            for (int i = 2; i < 6; i++)
            {
                answers.Add(reader.GetString(i));
            }
            int themeId = reader.GetInt32(6);
            string inputType = reader.GetString(7);
            QuestionData data = new QuestionData(id, title, answers, themeId, inputType);
            Questions.Add(data);
        }
    }
    reader.Close();
}

Далее данные легко получить и добавить в любые контролы

label1.Text = Questions[0].Title;
radioButton1.Text = Questions[0].Answers[0];
radioButton2.Text = Questions[0].Answers[1];
radioButton3.Text = Questions[0].Answers[2];
radioButton4.Text = Questions[0].Answers[3];

Но я бы конечно динамически создавал контролы на основе данных, полученных из базы, и в базе ответы бы хранил в отдельной таблице с привязкой к id вопроса, таким образом можно было бы добавить одному вопросу любое количество вариантов ответов, а не столько, сколько вы завели колонок. Ответы получать можно было бы отдельным запросом в базе.

Но для начала, я думаю, вам и того что я выше написал хватит. Разберитесь, как это работает обязательно.

Напоследок, вот здесь проблема

string sql = $"SELECT * FROM Questions WHERE ID_theme = '{Test.Theme_ID}'";

Если вы добавите колонку между существующими, или поменяете колонки местами, все сломается, чтобы избежать такой проблемы при изменении структуры базы данных, имена колонок в запросе надо указать явно.

string sql = $"SELECT ID,Question_title,Answer_variant_1,Answer_variant_2,Answer_variant_3,Answer_variant_4,ID_theme,Input_type FROM Questions WHERE ID_theme = '{Test.Theme_ID}'";

Кстати, а зачем читать каждую тему по отдельности? Читайте все сразу, как раз методом что выше, у вас же не десятки тысяч этих вопросов?

string sql = "SELECT ID,Question_title,Answer_variant_1,Answer_variant_2,Answer_variant_3,Answer_variant_4,ID_theme,Input_type FROM Questions";

А тему выбирайте уже из прочитанных данных

List<QuestionData> themeQuestions = Questions.Where(x => x.ThemeId == Test.Theme_ID).ToList();

И вот вам пожалуйста, список только тех вопросов, которые соответствуют нужной теме.

→ Ссылка