Какво правим тук
Този урок е практикум — четири учебни часа, в които довършваш функционалността от предишните два. Всяка задача носи по един нов проблем, който неминуемо изниква при работа с истинска база.
Ключово
Тук се учиш на неща, които не се виждат в готовия код: датата идва с час, дългите заявки се строят трудно и грешат, а програмата спира аварийно точно когато потребителят направи нещо неочаквано.
Задача 1 — датата носи и час
Добави във формата останалите атрибути на таблицата Student. При датата обаче има уловка: C# няма променлива, която да съхранява само дата. Дори атрибутът в SQL Server да е от тип date, при преминаване в C# стойността му се пази в променлива от тип DateTime — и към нея автоматично се добавя време 00:00:00, което после се показва в текстовата кутия.
DateTime DaT = (DateTime)reader[5];
studBornDateBox.Text = DaT.ToShortDateString();Бележка
ToShortDateString() се съобразява с регионалните настройки на машината — на един компютър ще изведе 5.12.2002, на друг 12/5/2002. Когато форматът трябва да е един и същ навсякъде, задай го изрично: DaT.ToString("dd.MM.yyyy").
Задача 2 — добавяне на нов ученик
Формата може да служи и за въвеждане на нови редове. Добавяш бутон „Нов“, а методът зад него е почти същият като при „Запази“ — само построяването на UPDATE се заменя с построяване на INSERT INTO:
string queryString = "INSERT INTO Student (name,surname," + "family,egn," +
"birth_date,birth_place,district,e_mail) VALUES ('"
+ studNameBox.Text + "','" + studSurnameBox.Text + "','"
+ studFamilyBox.Text + "','" + studEGNBox.Text + "','"
+ studBornDateBox.Text + "','" + studBornPlaceBox.Text + "','"
+ studDistrictBox.Text + "','" + studMailBox.Text + "');";
// MessageBox.Show(queryString);- Дългите заявки се строят трудно и в тях лесно се допускат грешки — сървърът отказва да изпълни синтактично неправилен оператор. Затова по време на разработката покажи построената заявка с
MessageBox.Show(queryString), а като се увериш, че е наред, върни реда в коментар. - Заявката ще мине без
idStudentсамо ако той е ключ с автоматично задавани стойности. Ако не е, трябва да включиш и него в списъка от атрибути, а стойността да вземеш от кутията — лош вариант, защото тогава потребителят трябва да решава какъв идентификатор е свободен.
Задача 3 — търсене по няколко полета
Разшири търсенето: не само по идентификатор, а и по другите атрибути. Идеята е да проверяваш кои текстови кутии са непразни и за всяка непразна да добавяш елемент в клаузата WHERE:
if (studNameBox.Text != "")
queryString += " name = '" + studNameBox.Text + "'";Внимание
Внимавай, ако непразните кутии станат две. Долепени една след друга, условията дават WHERE name = 'Огнян' family = 'Трайчев' — синтактична грешка. Между условията трябва да влезе AND, а най-чисто е да ги събереш в списък и да ги съединиш накрая.
Задачи 4 и 5 — когато програмата спре аварийно
При работа с формата възникват най-различни непредвидени ситуации. Опитай нарочно:
- да търсиш, без да си задал стойност за аргумент;
- да търсиш с идентификатор, който не съществува в таблицата;
- да записваш, преди изобщо да си прочел данни.
Наблюдавай реакцията на програмата. В случаите, когато спира аварийно, си припомни механизма за изключения и го използвай, за да прихванеш спирането и да изведеш подходящо съобщение вместо него.
try
{ reader.Read();
studNameBox.Text = reader[1].ToString();
}
catch (InvalidOperationException)
{ MessageBox.Show("Няма ученик с този идентификатор.");
}Задача 5
Регистрирай ситуациите, в които си предизвикал аварийно спиране, и начина, по който си се справил. Обсъдете ги със съучениците си — един вече може да е решил проблема, който на теб ти предстои.
Задача 6 — и другите таблици
По модела на формата за Student направи вторични форми за разглеждане, редактиране и допълване и на другите таблици. Започни със School_data — тя има само един ред, така че функционалността се изработва лесно (добавянето на нов ред там е безсмислено).
Какво трябва да запомниш
- Датата от базата идва като
DateTimeс час00:00:00— форматирай я, преди да я покажеш. INSERTможе да пропусне първичния ключ само ако той се задава автоматично от сървъра.- Показвай построената заявка, докато я разработваш — така грешката се вижда веднага.
- Условията в
WHEREсе съединяват сAND, не се долепват едно до друго. - Всяко действие на потребителя, което може да няма резултат, се обгражда с
try … catch.