LINQ – Group Join và Outer Join (Left Join, Right Join)
Cập nhật :16/10/2013
Bằng cách kết hợp join và into, ta có thể kết nhiều tập dữ liệu và kết quả trả về sẽ được nằm trong một cấu trúc phân cấp tương tự như GroupBy. Một đặc điểm của Group Join là tập dữ liệu bên trái sẽ được lấy tất cả, không quan tâm chúng có được so khớp trùng với tập dữ liệu bên phải hay không. Từ đó, ta có thể áp dụng để thực hiện outer join với LINQ.
 Bằng cách kết hợp join và into, ta có thể kết nhiều tập dữ liệu và kết quả trả về sẽ được nằm trong một cấu trúc phân cấp tương tự như GroupBy. Một đặc điểm của Group Join là tập dữ liệu bên trái sẽ được lấy tất cả, không quan tâm chúng có được so khớp trùng với tập dữ liệu bên phải hay không. Từ đó, ta có thể áp dụng để thực hiện outer join với LINQ.
Group Join
Như các bài viết trước tôi cung cấp một ví quen thuộc sau:
04 |
public string ProductName; |
05 |
public int CategoryID; |
07 |
public Product( int id, string name, int categoryId) |
10 |
this .ProductName=name; |
11 |
this .CategoryID=categoryId; |
16 |
public int CategoryID; |
17 |
public string CategoryName; |
19 |
public Category( int id, string name) |
22 |
this .CategoryName=name; |
27 |
var products= new Product[]{ |
28 |
new Product(1, "PowerPoint" ,100), |
29 |
new Product(2, "Excel" ,100), |
30 |
new Product(3, "Photoshop" ,101), |
31 |
new Product(4, "TuneUp" ,105), |
33 |
var categories= new Category[]{ |
34 |
new Category(100, "Microsoft" ), |
35 |
new Category(101, "Adobe" ), |
36 |
new Category(102, "Sun" ) |
Ví dụ sau sẽ xuất ra một bảng phân loại sản phẩm theo category trong LINQPAD:
2 |
join c in categories on p.CategoryID equals c.CategoryID into catGroup |
6 |
Category=cat.CategoryName, |
IEnumerable<> (3 items) |
Category |
Products |
Microsoft |
Product |
UserQuery+Product |
ProductID |
1 |
ProductName |
PowerPoint |
CategoryID |
100 |
|
Microsoft |
Product |
UserQuery+Product |
ProductID |
2 |
ProductName |
Excel |
CategoryID |
100 |
|
Adobe |
Product |
UserQuery+Product |
ProductID |
3 |
ProductName |
Photoshop |
CategoryID |
101 |
|
Outer Join:Left Join và Right Join
Vận dụng Group Join, bạn có thể thực hiện các phép kết Outer Join. Để thực hiện điều này, ta dùng extension method DefaultIfEmpy() của LINQ. Phương thức này sẽ lấy giá trị mặc định nếu như dữ liệu là rỗng. Trong trường hợp này giá trị mặc định đó sẽ là null. Left Join được minh họa như hình dưới đây với vùng được tô màu là phần dữ liệu trả về sau khi thực hiện:

Trong câu truy vấn bạn cũng cần phải kiểm tra trường hợp dữ liệu bằng null để xử lý thích hợp. Ví dụ sau thực hiện left join với products và categories, để thực hiện right join, bạn chỉ cần đổi thứ tự hai tập hợp lại:
Query Syntax:
2 |
join c in categories on p.CategoryID equals c.CategoryID into catGroup |
3 |
from cat in catGroup.DefaultIfEmpty() |
6 |
Category=cat== null ? "<null>" :cat.CategoryName, |
Method Syntax:
14 |
temp0 => temp0.catGroup.DefaultIfEmpty (), |
18 |
Category = (cat == null ) ? "<null>" : cat.CategoryName, |
19 |
Product = temp0.p.ProductName |
Kết quả:
IEnumerable<> (4 items) |
Category |
Product |
Microsoft |
PowerPoint |
Microsoft |
Excel |
Adobe |
Photoshop |
<null> |
TuneUp
|
|