Xây dựng ứng dụng quản lý sinh viên sử dụng ADO.NET và SQL Server

Bài tập này hướng dẫn bạn cách thực hiện các thao tác CRUD (Create, Read, Update, Delete) cơ bản trên cơ sở dữ liệu SQL Server thông qua ADO.NET trong môi trường Console Application của C#. Chúng ta sẽ thực hiện quản lý danh sách sinh viên kết hợp với thông tin chuyên ngành.

1. Thiết lập cơ sở dữ liệu

Đầu tiên, chúng ta cần tạo cơ sở dữ liệu và cấu trúc các bảng. Sử dụng đoạn mã SQL sau để khởi tạo bảng Majors (Chuyên ngành) và Students (Sinh viên).

CREATE DATABASE StudentManagement;
GO
USE StudentManagement;
GO

-- Bảng Chuyên ngành
CREATE TABLE Majors (
    MajorId NVARCHAR(20) PRIMARY KEY,
    MajorName NVARCHAR(100) NOT NULL
);

-- Bảng Sinh viên
CREATE TABLE Students (
    StudentId NVARCHAR(20) PRIMARY KEY,
    FullName NVARCHAR(100) NOT NULL,
    Gender BIT NOT NULL, -- 1: Nam, 0: Nữ
    BirthDate DATETIME NOT NULL,
    MajorId NVARCHAR(20) FOREIGN KEY REFERENCES Majors(MajorId)
);

-- Chèn dữ liệu mẫu
INSERT INTO Majors VALUES ('M01', N'Công nghệ thông tin'), ('M02', N'Kinh tế quốc tế');
INSERT INTO Students VALUES ('S001', N'Nguyễn Văn An', 1, '2002-05-15', 'M01');
INSERT INTO Students VALUES ('S002', N'Trần Thị Bình', 0, '2003-08-20', 'M02');

2. Định nghĩa lớp dữ liệu (Model)

Lớp StudentInfo sẽ đại diện cho đối tượng sinh viên trong mã nguồn C#, bao gồm các thuộc tính hỗ trợ tính toán tuổi và định dạng hiển thị.

using System;
using System.Data.SqlClient;

namespace StudentApp.Models
{
    public class StudentInfo
    {
        public string StudentId { get; set; }
        public string FullName { get; set; }
        public bool Gender { get; set; }
        public DateTime BirthDate { get; set; }
        public string MajorId { get; set; }

        public string GenderText => Gender ? "Nam" : "Nữ";
        public string FormattedDOB => BirthDate.ToString("yyyy-MM-dd");
        public int Age => DateTime.Now.Year - BirthDate.Year;

        // Phương thức lấy tên chuyên ngành dựa trên MajorId
        public string GetMajorName(string connectionString)
        {
            string name = "";
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                string sql = "SELECT MajorName FROM Majors WHERE MajorId = @id";
                SqlCommand cmd = new SqlCommand(sql, conn);
                cmd.Parameters.AddWithValue("@id", MajorId);
                conn.Open();
                var result = cmd.ExecuteScalar();
                if (result != null) name = result.ToString();
            }
            return name;
        }
    }
}

3. Lớp xử lý dữ liệu (Data Access Layer)

Lớp StudentService tập trung các phương thức tương tác trực tiếp với SQL Server như truy vấn, thêm, sửa, xóa.

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using StudentApp.Models;

namespace StudentApp.Services
{
    public class StudentService
    {
        private readonly string _connStr = "server=.;database=StudentManagement;Integrated Security=SSPI;";

        public List<StudentInfo> FetchAll()
        {
            var list = new List<StudentInfo>();
            using (SqlConnection conn = new SqlConnection(_connStr))
            {
                string sql = "SELECT * FROM Students";
                SqlCommand cmd = new SqlCommand(sql, conn);
                conn.Open();
                SqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    list.Add(new StudentInfo
                    {
                        StudentId = reader["StudentId"].ToString(),
                        FullName = reader["FullName"].ToString(),
                        Gender = Convert.ToBoolean(reader["Gender"]),
                        BirthDate = Convert.ToDateTime(reader["BirthDate"]),
                        MajorId = reader["MajorId"].ToString()
                    });
                }
            }
            return list;
        }

        public bool CheckExists(string id)
        {
            using (SqlConnection conn = new SqlConnection(_connStr))
            {
                SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM Students WHERE StudentId = @id", conn);
                cmd.Parameters.AddWithValue("@id", id);
                conn.Open();
                return (int)cmd.ExecuteScalar() > 0;
            }
        }

        public string GetMajorIdByName(string majorName)
        {
            using (SqlConnection conn = new SqlConnection(_connStr))
            {
                SqlCommand cmd = new SqlCommand("SELECT MajorId FROM Majors WHERE MajorName = @name", conn);
                cmd.Parameters.AddWithValue("@name", majorName);
                conn.Open();
                var result = cmd.ExecuteScalar();
                return result?.ToString();
            }
        }

        public void ExecuteInsert(StudentInfo s)
        {
            using (SqlConnection conn = new SqlConnection(_connStr))
            {
                string sql = "INSERT INTO Students VALUES(@id, @name, @gender, @dob, @mid)";
                SqlCommand cmd = new SqlCommand(sql, conn);
                cmd.Parameters.AddWithValue("@id", s.StudentId);
                cmd.Parameters.AddWithValue("@name", s.FullName);
                cmd.Parameters.AddWithValue("@gender", s.Gender);
                cmd.Parameters.AddWithValue("@dob", s.BirthDate);
                cmd.Parameters.AddWithValue("@mid", s.MajorId);
                conn.Open();
                cmd.ExecuteNonQuery();
            }
        }

        public void ExecuteUpdate(StudentInfo s)
        {
            using (SqlConnection conn = new SqlConnection(_connStr))
            {
                string sql = "UPDATE Students SET FullName=@name, Gender=@gender, BirthDate=@dob, MajorId=@mid WHERE StudentId=@id";
                SqlCommand cmd = new SqlCommand(sql, conn);
                cmd.Parameters.AddWithValue("@id", s.StudentId);
                cmd.Parameters.AddWithValue("@name", s.FullName);
                cmd.Parameters.AddWithValue("@gender", s.Gender);
                cmd.Parameters.AddWithValue("@dob", s.BirthDate);
                cmd.Parameters.AddWithValue("@mid", s.MajorId);
                conn.Open();
                cmd.ExecuteNonQuery();
            }
        }

        public void ExecuteDelete(string id)
        {
            using (SqlConnection conn = new SqlConnection(_connStr))
            {
                SqlCommand cmd = new SqlCommand("DELETE FROM Students WHERE StudentId = @id", conn);
                cmd.Parameters.AddWithValue("@id", id);
                conn.Open();
                cmd.ExecuteNonQuery();
            }
        }

        public string GetConnStr() => _connStr;
    }
}

4. Điều khiển chương trình (Main Program)

Dưới đây là logic chính để xử lý luồng nhập liệu từ người dùng và gọi các phương thức xử lý dữ liệu tương ứng.

using System;
using StudentApp.Models;
using StudentApp.Services;

namespace StudentApp
{
    class Program
    {
        static StudentService service = new StudentService();

        static void Main(string[] args)
        {
            Console.OutputEncoding = System.Text.Encoding.UTF8;
            while (true)
            {
                ShowData();
                Console.WriteLine("\nChọn thao tác: 1.Thêm | 2.Sửa | 3.Xóa | Khác.Thoát");
                string choice = Console.ReadLine();

                switch (choice)
                {
                    case "1": AddProcess(); break;
                    case "2": UpdateProcess(); break;
                    case "3": DeleteProcess(); break;
                    default: return;
                }
            }
        }

        static void ShowData()
        {
            var list = service.FetchAll();
            Console.WriteLine("\n{0,-10} {1,-20} {2,-10} {3,-5} {4,-15} {5}", "Mã SV", "Họ Tên", "Giới Tính", "Tuổi", "Ngày Sinh", "Chuyên Ngành");
            foreach (var s in list)
            {
                Console.WriteLine("{0,-10} {1,-20} {2,-10} {3,-5} {4,-15} {5}", 
                    s.StudentId, s.FullName, s.GenderText, s.Age, s.FormattedDOB, s.GetMajorName(service.GetConnStr()));
            }
        }

        static void AddProcess()
        {
            StudentInfo s = new StudentInfo();
            
            while (true)
            {
                Console.Write("Nhập mã SV mới: ");
                s.StudentId = Console.ReadLine();
                if (!service.CheckExists(s.StudentId)) break;
                Console.WriteLine("Mã đã tồn tại!");
            }

            Console.Write("Nhập họ tên: ");
            s.FullName = Console.ReadLine();

            Console.Write("Giới tính (Nam/Nữ): ");
            s.Gender = Console.ReadLine() == "Nam";

            Console.Write("Ngày sinh (yyyy/mm/dd): ");
            s.BirthDate = DateTime.Parse(Console.ReadLine());

            while (true)
            {
                Console.Write("Nhập tên chuyên ngành: ");
                string mName = Console.ReadLine();
                s.MajorId = service.GetMajorIdByName(mName);
                if (s.MajorId != null) break;
                Console.WriteLine("Không tìm thấy chuyên ngành này!");
            }

            Console.WriteLine("Xác nhận thêm? (Y/N)");
            if (Console.ReadLine().ToUpper() == "Y")
            {
                service.ExecuteInsert(s);
                Console.Clear();
                Console.WriteLine("Thêm thành công!");
            }
        }

        static void DeleteProcess()
        {
            Console.Write("Nhập mã SV cần xóa: ");
            string id = Console.ReadLine();
            if (service.CheckExists(id))
            {
                Console.Write("Bạn có chắc chắn muốn xóa SV này? (Y/N): ");
                if (Console.ReadLine().ToUpper() == "Y")
                {
                    service.ExecuteDelete(id);
                    Console.Clear();
                    Console.WriteLine("Đã xóa sinh viên.");
                }
            }
            else
            {
                Console.WriteLine("Không tìm thấy sinh viên.");
            }
        }

        static void UpdateProcess()
        {
            Console.Write("Nhập mã SV cần sửa: ");
            string id = Console.ReadLine();
            if (service.CheckExists(id))
            {
                // Thực hiện tương tự logic AddProcess nhưng sử dụng ExecuteUpdate
                // Lưu ý: Giữ nguyên StudentId, chỉ thay đổi các trường còn lại.
            }
            else
            {
                Console.WriteLine("Mã sinh viên không hợp lệ.");
            }
        }
    }
}

Thẻ: ADO.NET SQL Server c-sharp CRUD Database-Programming

Đăng vào ngày 5 tháng 10 lúc 03:28