ใน LINQ มีการจอยน์ (Join) หลายแบบ ซึ่งแตกต่างกันในการจัดการข้อมูลที่ไม่ตรงกัน (Non-matching elements):
- INNER JOIN: นำเฉพาะข้อมูลที่ตรงกัน (Matching elements) เข้ามาในผลลัพธ์
- LEFT OUTER JOIN: นำข้อมูลที่ตรงกันทั้งหมด รวมถึงข้อมูลที่ไม่ตรงจากฝั่งซ้าย (Left collection) เข้ามาในผลลัพธ์
ตัวอย่าง: สมมติมีคลาส Department และ Employee พนักงานชื่อ Mary ไม่มีแผนก (DepartmentID เป็น null) INNER JOIN จะไม่แสดง Mary แต่ LEFT OUTER JOIN จะแสดงพร้อมค่า "No Department"
ตัวอย่างโค้ด
static class Program
{
static void Main(string[] args)
{
var result = Employee.GetAllEmployees()
.GroupJoin(Department.GetAllDepartments(),
e => e.DepartmentID,
d => d.ID,
(emp, depts) => new { emp, depts })
.SelectMany(z => z.depts.DefaultIfEmpty(),
(a, b) => new
{
EmployeeName = a.emp.Name,
DepartmentName = b == null ? "No Department" : b.Name
});
foreach (var v in result)
{
Console.WriteLine(" " + v.EmployeeName + "\t" + v.DepartmentName);
}
}
}
public class Department
{
public int ID { get; set; }
public string Name { get; set; }
public static List<Department> GetAllDepartments()
{
return new List<Department>()
{
new Department { ID = 1, Name = "IT" },
new Department { ID = 2, Name = "HR" }
};
}
}
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public int? DepartmentID { get; set; } // ใช้ nullable เพื่อรองรับไม่มีแผนก
public static List<Employee> GetAllEmployees()
{
return new List<Employee>()
{
new Employee { ID = 1, Name = "Mark", DepartmentID = 1 },
new Employee { ID = 2, Name = "Steve", DepartmentID = 2 },
new Employee { ID = 3, Name = "Ben", DepartmentID = 1 },
new Employee { ID = 4, Name = "Philip", DepartmentID = 1 },
new Employee { ID = 5, Name = "Mary" } // ไม่มี DepartmentID
};
}
}
ผลลัพธ์
Mark IT
Steve HR
Ben IT
Philip IT
Mary No Department
คำอธิบายสำคัญ
GroupJoin: จัดกลุ่มข้อมูลจากฝั่งขวา (Right) ตามคีย์DefaultIfEmpty(): หากไม่มีข้อมูลตรงกัน จะคืนค่า default (null สำหรับ reference type)SelectMany: รวมผลลัพธ์จากกลุ่มข้อมูลเข้าด้วยกัน