Truy vấn dữ liệu cơ bản với EF Core
Việc thực hiện truy vấn luôn làm việc với
Linq,
nên đảm bảo thêm namespace System.Linq
vào.
Hãy copy mã nguồn bài trước (Fluent API),
đổi tên thư mục thành ef04 để thực hành.
Truy vấn để lấy dữ liệu từ EF cơ bản viết các câu lệnh LINQ phù hợp trên các nguồn dữ liệu (các DbSet). Sau đây là một số ví dụ:
Ví dụ, lấy tất cả các sản phẩm
Truy vấn dữ liệu trực tiếp từ các DbSet
Với các DbSet (Table) mặc định được giám sát bởi EF, khi truy cập để đọc các phần tử (hàng) nó sẽ tự động truy cấn lấy dữ liệu về. Đồng thời sử dụng các hàm có trong DbSet có thể lọc, giới hạn, tìm kiếm ... Ví dụ, lấy các sản phẩm tử bảng Product
using (var context = new ShopContext ()) { var products = context.products; // var products = await context.products.ToListAsync (); nếu muốn dùng async foreach (var pro in products) { Console.WriteLine (pro.Name); } }
Vì các DbSet triển khai từ Queryable, nên có thể dùng trực tiếp nhiều phương thức của nó như: Where, Take, Contain ...
Ví dụ lấy ra 2 sản phẩm, sản sắp xếp giảm dần theo giá, chỉ các sản phẩm có giá trên 100
var products = context.products .Where(p => p.Price > 100) // Lọc các sản phẩm giá trên 100 .OrderByDescending(p => p.Price) // Sắp xếp giảm dần, tăng dần là OrderBy .Take(2); // Chỉ lấy 2 dòng đầu
Ngoài ra bạn có thể sử dụng Sum
để tính tổng, Average
tính trung bình ...
Để tìm một dòng dữ liệu theo PK Key, thì dùng FindAsync
// Tìm sản phẩm có ID bằng 6 var product = await context.products.FindAsync(6); if (product != null) Console.WriteLine($"{product.Name}");
Lấy phần tử đầu tiên thỏa mãn điều kiện
using (var context = new ShopContext()) { // Sản phẩm đầu tiên scó giá trên 100, bắt đầu bằng chữ S var product = await context.products.FirstOrDefaultAsync(p => (p.Price > 100 && p.Name.StartsWith("S"))); if (product != null) Console.WriteLine($"{product.Name}"); }
Bạn có thể viết câu LINQ
var products = await (from p in context.products select p).ToListAsync(); foreach (var pro in products) { Console.WriteLine(pro.Name); }
Cũng có thể áp dụng kỹ thuật async để duyệt qua từng phần tử.
using (var context = new ShopContext()) { var products = (from p in context.products select p) .ToAsyncEnumerable(); await products.ForEachAsync( p => { Console.WriteLine($"{p.Name} - {p.Price}"); } ); }
Truy vấn kết hợp nhiều bảng với join
Sử dụng inner join
// Truy vấn lấy các sản phẩm (tên, giá) và tên danh mục của sản phẩm var products = from p in context.products join c in context.categories on p.CategoryId equals c.CategoryId // where p.ProductId == 2 select new { tensanpham = p.Name, gia = p.Price, danhmuc = c.Name }; foreach (var item in products) { Console.WriteLine($"{item.tensanpham} giá {item.gia} danh mục {item.danhmuc}"); }
Sử dụng left join
Đầu tiên xem truy vấn sau, lấy sản phẩm và tên danh mục thứ 2 của sản phẩm
var products = from p in context.products join c in context.categories on p.CategorySecondId equals c.CategoryId // where p.ProductId == 2 select new { tensanpham = p.Name, gia = p.Price, danhmuc = c.Name }; foreach (var item in products) { Console.WriteLine($"{item.tensanpham} giá {item.gia} danh mục {item.danhmuc}"); } // Sản phẩm 2 giá 11.0000 danh mục Cate2 // Sản phẩm 5(1) giá 333.0000 danh mục Cate2
Câu truy vấn trên là inner join, sản phẩm phải có danh mục thứ 2 mới được lấy ra, sản phẩm nào không có danh mục thứ 2 bị loại bỏ. Trong trường hợp, nếu muốn lấy tất cả các sản phẩm, kể cả trường hợp danh mục thứ 2 của nó không tồn tại, thì dùng left join như sau:
// Thi hành DefaultIfEmpty() trên tập kết quả right của Join để thực hiện left join var products = from p in context.products join c in context.categories on p.CategorySecondId equals c.CategoryId into t from cate2 in t.DefaultIfEmpty() // where p.ProductId == 2 select new { tensanpham = p.Name, gia = p.Price, danhmuc = (cate2 == null) ? "KHÔNG CÓ" : cate2.Name }; foreach (var item in products) { Console.WriteLine($"{item.tensanpham} giá {item.gia} danh mục {item.danhmuc}"); } // Sản phẩm 4(1) giá 323.0000 danh mục KHÔNG CÓ // Sản phẩm 3 giá 33.0000 danh mục KHÔNG CÓ // Sản phẩm 2 giá 11.0000 danh mục Cate2 // Sản phẩm 1 giá 12.0000 danh mục KHÔNG CÓ // Sản phẩm 5(1) giá 333.0000 danh mục Cate2
Truy vấn dữ với Raw Query
Trên một bảng (nguồn dữ liệu) bạn có thể thi hành trực tiếp câu truy vấn SQL, ví dụ:
using (var context = new ShopContext ()) { String sql = "select * from products order by Price Desc"; var products = context.products.FromSqlRaw(sql); await products.ForEachAsync(p => { Console.WriteLine(p.Name); }); }
Các hàm trong EF
Có các hàm xây dựng sẵn trong EF.Functions.
như Like
var products = await (from p in context.products where EF.Functions.Like(p.Name, "%phẩm%") select p) .ToListAsync();
Tham khảo mã nguồn: EF/ef04 hoặc tải về ex044