Этап 2. База данных и слои приложения¶
Задание¶
Создайте структуру базы данных и подготовьте основу приложения.
Ход работы¶
На этом этапе создается проект Windows Forms или WPF, подключается пакет Microsoft.Data.Sqlite, добавляется структура папок и создаются классы доступа к базе данных. В базе должны появиться системные таблицы Roles, Users, LoginAttempts и не менее трех таблиц выбранной предметной области.
Работа в проекте¶
Сначала создайте проект и убедитесь, что он запускается с пустым окном. Затем добавьте SQLite, создайте AppConfig, DbConnectionFactory и DatabaseInitializer. Вызов DatabaseInitializer.Initialize() выполняется до открытия первой формы или окна. После первого запуска рядом с приложением должен появиться файл practice.db, который можно открыть через DB Browser for SQLite.
Команды¶
Windows Forms:
WPF:
Рекомендуемая структура проекта¶
ProjectName/
Models/
User.cs
Role.cs
LoginAttempt.cs
Data/
DbConnectionFactory.cs
UserRepository.cs
<Entity>Repository.cs
Services/
AuthService.cs
CaptchaService.cs
PasswordHasher.cs
Forms/ или Views/
LoginForm.cs / LoginWindow.xaml
RegisterForm.cs / RegisterWindow.xaml
MainForm.cs / MainWindow.xaml
Минимальный набор классов этапа¶
| Файл | Назначение |
|---|---|
Models/User.cs |
модель пользователя |
Models/Book.cs или аналог |
модель предметной сущности |
Data/DbConnectionFactory.cs |
создание подключения к БД |
Data/DatabaseInitializer.cs |
создание таблиц и начальных данных |
Data/UserRepository.cs |
запросы к таблице пользователей |
Data/<Entity>Repository.cs |
запросы к предметной таблице |
Строка подключения и фабрика¶
using Microsoft.Data.Sqlite;
public static class DbConnectionFactory
{
public static SqliteConnection Create()
{
return new SqliteConnection(AppConfig.ConnectionString);
}
}
Инициализация SQLite¶
Ниже приведен фрагмент для системных таблиц и предметной области «Библиотека». В своем варианте замените Authors и Books на таблицы выбранной предметной области.
using Microsoft.Data.Sqlite;
public static class DatabaseInitializer
{
public static void Initialize()
{
using var connection = DbConnectionFactory.Create();
connection.Open();
Execute(connection, """
CREATE TABLE IF NOT EXISTS Roles (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Name TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS Users (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Login TEXT NOT NULL UNIQUE,
PasswordHash TEXT NOT NULL,
PasswordSalt TEXT NOT NULL,
FullName TEXT NOT NULL,
RoleId INTEGER NOT NULL,
IsActive INTEGER NOT NULL DEFAULT 1,
CreatedAt TEXT NOT NULL,
FOREIGN KEY (RoleId) REFERENCES Roles(Id)
);
CREATE TABLE IF NOT EXISTS LoginAttempts (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
UserLogin TEXT NOT NULL,
IsSuccess INTEGER NOT NULL,
Message TEXT NOT NULL,
CreatedAt TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS Authors (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
FullName TEXT NOT NULL,
Country TEXT
);
CREATE TABLE IF NOT EXISTS Books (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Title TEXT NOT NULL,
AuthorId INTEGER NOT NULL,
Year INTEGER,
InventoryNumber TEXT NOT NULL UNIQUE,
IsAvailable INTEGER NOT NULL DEFAULT 1,
FOREIGN KEY (AuthorId) REFERENCES Authors(Id)
);
""");
Execute(connection, "INSERT OR IGNORE INTO Roles (Id, Name) VALUES (1, 'admin'), (2, 'operator'), (3, 'user');");
Execute(connection, "INSERT OR IGNORE INTO Authors (Id, FullName, Country) VALUES (1, 'А. С. Пушкин', 'Россия');");
Execute(connection, "INSERT OR IGNORE INTO Books (Id, Title, AuthorId, Year, InventoryNumber, IsAvailable) VALUES (1, 'Капитанская дочка', 1, 1836, 'B-0001', 1);");
}
private static void Execute(SqliteConnection connection, string sql)
{
using var command = connection.CreateCommand();
command.CommandText = sql;
command.ExecuteNonQuery();
}
}
Для Windows Forms вызов инициализации размещается в Program.cs:
ApplicationConfiguration.Initialize();
DatabaseInitializer.Initialize();
Application.Run(new LoginForm());
Для WPF вызов можно выполнить в App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
DatabaseInitializer.Initialize();
new LoginWindow().Show();
}
К этапу прикладываются ER-схема, SQL-скрипт, описание таблиц, скриншот созданной базы и описание структуры проекта.