🔒

Đăng ký để xem nội dung này

Tạo tài khoản miễn phí và đăng ký gói học để truy cập toàn bộ bài học, video và tài liệu độc quyền.

Đăng ký ngay — Miễn phí Đã có tài khoản? Đăng nhập

Hiển thị danh sách dữ liệu bằng LINQ

 

🎓 BÀI GIẢNG: HIỂN THỊ DANH SÁCH DỮ LIỆU BẰNG LINQ TRONG SERVICE (.NET 8, EF CORE)


💡 Mục tiêu

  • Biết cách tạo class Service cho từng bảng.

  • Biết tiêm Dependency (DI) để sử dụng DbContext.

  • Thực hành các kiểu truy vấn LINQ phổ biến:
    👉 OrderBy, Join, Where, Paging, Select ViewModel.


1️⃣ Tạo class Service và cấu hình Dependency Injection

🔹 Model

public partial class KhoaHoc
{  
    public int ID { get; set; }
    public string TenKhoaHoc { get; set; }
    public int? idChuDe { get; set; }
    public int? ThuTu { get; set; }
    public string HinhAnh { get; set; }
    public string MoTa { get; set; }
    public string BaiViet { get; set; }
    public string GiangVien { get; set; }
    public DateOnly? ThoiGianTao { get; set; }
    public bool? isCongKhai { get; set; }
    public virtual ChuDe idChuDeNavigation { get; set; }
    public virtual ICollection<DangKyKhoaHoc> DangKyKhoaHocs { get; set; } = new List<DangKyKhoaHoc>();
    public virtual ICollection<Video> Videos { get; set; } = new List<Video>();
}

🔹 DbContext

public class AppDbContext : DbContext
{
    public DbSet<KhoaHoc> KhoaHocs { get; set; }
    public DbSet<ChuDe> ChuDes { get; set; }
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
}

🔹 Service

public class KhoaHocService
{
    private readonly AppDbContext _db;
    public KhoaHocService(AppDbContext db)
    {
        _db = db;
    }
}

👉 Trong Program.cs:

builder.Services.AddScoped<KhoaHocService>();

👉 Trong KhoaHocController.cs:

public class KhoaHocController : Controller
{
    private readonly KhoaHocService _service;
    public KhoaHocController(KhoaHocService service)
    {
        _service = service;
    }
    public IActionResult DanhSach()
    {
        var list = _service.GetAll();
        return View(list);
    }
}

📋 2️⃣ Hàm get danh sách cơ bản (OrderBy, Count, Sum)

public List<KhoaHoc> GetAll()
{
    return _db.KhoaHocs
              .OrderByDescending(x => x.ThoiGianTao)
              .ToList();
}

public int TongKhoaHoc()
{
    return _db.KhoaHocs.Count();
}

public int SoLuongCongKhai()
{
    return _db.KhoaHocs.Count(x => x.isCongKhai == true);
}

🔗 3️⃣ Hàm get danh sách có INNER JOIN với bảng ChuDe

public List<dynamic> GetJoinChuDe()
{
    var query = from kh in _db.KhoaHocs
                join cd in _db.ChuDes on kh.idChuDe equals cd.ID
                orderby kh.ThoiGianTao descending
                select new
                {
                    kh.ID,
                    kh.TenKhoaHoc,
                    cd.TenChuDe,
                    kh.GiangVien,
                    kh.ThoiGianTao
                };
    return query.ToList<dynamic>();
}

🧠 Tương đương SQL:

SELECT kh.ID, kh.TenKhoaHoc, cd.TenChuDe, kh.GiangVien, kh.ThoiGianTao
FROM KhoaHocs kh
JOIN ChuDes cd ON kh.idChuDe = cd.ID
ORDER BY kh.ThoiGianTao DESC

🔍 4️⃣ Hàm get danh sách có truy vấn WHERE (lọc tham số)

public List<KhoaHoc> GetByFilter(string? keyword, bool? congKhai, int? idChuDe)
{
    var query = _db.KhoaHocs.AsQueryable();

    if (!string.IsNullOrEmpty(keyword))
        query = query.Where(x => x.TenKhoaHoc.Contains(keyword) || x.MoTa.Contains(keyword));

    if (congKhai.HasValue)
        query = query.Where(x => x.isCongKhai == congKhai.Value);

    if (idChuDe.HasValue)
        query = query.Where(x => x.idChuDe == idChuDe.Value);

    return query
        .OrderByDescending(x => x.ThoiGianTao)
        .ToList();
}

🔎 LINQ tự động tạo câu SQL WHERE tương ứng chỉ với tham số có giá trị.


📄 5️⃣ Hàm danh sách có phân trang (Paging)

public List<KhoaHoc> GetPaging(int page = 1, int pageSize = 10)
{
    var query = _db.KhoaHocs
        .OrderByDescending(x => x.ThoiGianTao)
        .Skip((page - 1) * pageSize)
        .Take(pageSize);

    return query.ToList();
}

public int TongSoTrang(int pageSize)
{
    int total = _db.KhoaHocs.Count();
    return (int)Math.Ceiling((double)total / pageSize);
}

📘 SQL tương đương:

SELECT * FROM KhoaHocs
ORDER BY ThoiGianTao DESC
OFFSET (@page-1)*@pageSize ROWS FETCH NEXT @pageSize ROWS ONLY

🧱 6️⃣ Hàm danh sách trả về ViewModel mới

Khi bạn muốn hiển thị lên giao diện nhưng không cần toàn bộ trường của bảng.

🔹 ViewModel

public class KhoaHocVM
{
    public int ID { get; set; }
    public string TenKhoaHoc { get; set; }
    public string TenChuDe { get; set; }
    public string GiangVien { get; set; }
    public string NgayTaoText { get; set; }
    public string TrangThai { get; set; }
}

🔹 LINQ Select về ViewModel

public List<KhoaHocVM> GetViewModel()
{
    var query = from kh in _db.KhoaHocs
                join cd in _db.ChuDes on kh.idChuDe equals cd.ID into tmp
                from cd in tmp.DefaultIfEmpty() // left join
                orderby kh.ThoiGianTao descending
                select new KhoaHocVM
                {
                    ID = kh.ID,
                    TenKhoaHoc = kh.TenKhoaHoc,
                    TenChuDe = cd != null ? cd.TenChuDe : "(Chưa có chủ đề)",
                    GiangVien = kh.GiangVien,
                    NgayTaoText = kh.ThoiGianTao.HasValue
                        ? kh.ThoiGianTao.Value.ToString("dd-MM-yyyy")
                        : "",
                    TrangThai = kh.isCongKhai == true ? "Công khai" : "Riêng tư"
                };

    return query.ToList();
}

Ưu điểm:

  • Chỉ lấy dữ liệu cần hiển thị.

  • Có thể format trước khi trả ra View (ví dụ: NgayTaoText, TrangThai).

  • Không cần expose toàn bộ Entity ra ngoài.


🧠 Tổng kết bài học

Phần Nội dung Kỹ năng đạt được
1 Tạo Service + DI Tổ chức code sạch, tách tầng dữ liệu
2 Get cơ bản (OrderBy, Count, Sum) Thành thạo LINQ cơ bản
3 Get có Join Truy vấn nhiều bảng
4 Get có Where Lọc dữ liệu động
5 Get có Paging Làm phân trang với LINQ
6 Get ViewModel Tạo dữ liệu tối ưu cho View/UI

 

Bài tập số 13: Hiển thị danh sách dữ liệu bằng LINQ

Yêu cầu:

  1. Hiển thị danh sách tài khoản học viên

    • Truy vấn toàn bộ học viên, lọc theo thông tin, thời gian đăng ký từ ngày đến ngày, trạng thái đăng ký

    • Viết hàm đếm số lượng tổng học viên

  2. Hiển thị danh sách tài khoản quản lý

    • Truy vấn toàn bộ tài khoản, lọc theo thông tin, trạng thái hoạt động

Nộp bài: Tự làm bài cá nhân