LINQ Full Outer Join

LINQ Full Outer Join

في هذا الدرس، سنتعلّم كيف ننفّذ Full Outer Join في LINQ بلغة C#، بالرغم من إنه غير مدعوم مباشرة، لكن نقدر نحاكيه يدويًا باستخدام GroupJoin + DefaultIfEmpty() + Union.



ما هو Full Outer Join؟

يرجع كل العناصر من الجهتين (الموظفين + الأقسام)، حتى وإن لم يكن هناك تطابق. البيانات المفقودة يتم ملؤها بـ null أو قيمة افتراضية.



تعريف الكائنات:


public class Employee
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int? DepartmentID { get; set; }
}

public class Department
{
    public int ID { get; set; }
    public string DeptName { get; set; }
}

ملاحظة: استخدمنا int? لأن بعض الموظفين قد لا يكون لهم قسم.



البيانات:


List<Employee> employees = new List<Employee>()
{
    new Employee() { ID = 1, Name = "John", DepartmentID = 1 },
    new Employee() { ID = 2, Name = "Moin", DepartmentID = 1 },
    new Employee() { ID = 3, Name = "Bill", DepartmentID = 2 },
    new Employee() { ID = 4, Name = "Ram", DepartmentID = null }
};

List<Department> departments = new List<Department>()
{
    new Department(){ ID = 1, DeptName = "IT" },
    new Department(){ ID = 2, DeptName = "HR" },
    new Department(){ ID = 3, DeptName = "Finance" }
};


تنفيذ Full Outer Join:


// Left Outer Join
var leftJoin = from emp in employees
               join dept in departments
               on emp.DepartmentID equals dept.ID into deptGroup
               from dept in deptGroup.DefaultIfEmpty()
               select new
               {
                   EmployeeName = emp.Name,
                   DepartmentName = dept != null ? dept.DeptName : "No Department"
               };

// Right Outer Join
var rightJoin = from dept in departments
                join emp in employees
                on dept.ID equals emp.DepartmentID into empGroup
                from emp in empGroup.DefaultIfEmpty()
                where emp == null
                select new
                {
                    EmployeeName = "No Employee",
                    DepartmentName = dept.DeptName
                };

// Full Outer Join = Left + Right
var fullOuterJoin = leftJoin.Union(rightJoin);


الناتج:


Employee: John, Department: IT  
Employee: Moin, Department: IT  
Employee: Bill, Department: HR  
Employee: Ram, Department: No Department  
Employee: No Employee, Department: Finance


شرح:

  • Left Join: كل الموظفين مع أقسامهم، ولو مفيش قسم يتم وضع "No Department".
  • Right Join: كل الأقسام اللي مفيش موظفين ينتموا ليها، نكتب "No Employee".
  • Union: جمعنا النتيجتين في نتيجة واحدة تمثل Full Outer Join.


ملاحظات هامة:

  • Full Outer Join غير مدعوم صراحةً في LINQ.
  • يمكنك استخدام Concat بدل Union لو حابب تضم الكل حتى مع التكرار.
  • DefaultIfEmpty() مهمة جدًا لمحاكاة الـ Outer Join.


تعليقات

المشاركات الشائعة من هذه المدونة

C# - Arrays

Entity Framework - ما هو ORM؟ ونبذة عن Dapper وNHibernate

Entity Framework - مقدمة عن Entity Framework