Вывод трех строк одного столбца из базы данных в 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 шт):
Если по-простому, то как-то так.
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();
И вот вам пожалуйста, список только тех вопросов, которые соответствуют нужной теме.