فرض کنید یه جدول داریم به اسم WorkGroups که لیستی از واحدهای سازمان است. رابطه بین واحدها به صورت درختی در همین جدول وجود داره. یعنی یه فیلد داریم به نام ParentId که اگر پر باشه یعنی آی دی واحد بالاسری. سه دسته رکورد واحد داریم :
1. رده بالا : شامل رکوردهای میشه که ParentId شون null هست یعنی سطح بالا هستند و بقیه زیر مجموعه اینا هستن.
2. رده میانی : که شامل رکوردهایی هست که ParentId شون پر هست پس هم فرزند هستند هم پدر.
3. رده پایین : که شامل رکوردهایی هست که ParentId شون پر هست پس فرزند هستند ولی پدر نیستند. یعنی هیچ رکوردی وجود نداره که ParentId شون برابر Id این رکوردهای رده پایین باشه.
حالا با کد sql چه جوری این رکوردها رو تفکیک کنیم و سه تا لیست جدا از واحدهای رده بالا ، میانی و پایینی بدیم؟
جواب با کد Sql :
رده بالایی :
این واحدها خیلی ساده بدست میان :
select * from WorkGroups where ParentId is null
SELECT w.* FROM WorkGroups w WHERE w.ParentId is not null and exists (select * from Sajat.WorkGroups x where x.ParentId= w.id)
3. رده پایین :
SELECT w.* FROM WorkGroups w WHERE w.ParentId is not null and not exists (select * from Sajat.WorkGroups x where x.ParentId= w.id)
جواب با کد سی شارپ :
var workGroups = await _workGroupRepository.Get().ToListAsync();
1. رده بالا :
var level1 = workGroups.Where(w => w.ParentId == null).ToList();
2. رده میانی :
var level2 = workGroups.Where(w => w.ParentId != null && workGroups.Any(a => a.ParentId == w.Id)).ToList();
3. رده پایین :
var level3 = workGroups.Where(w => w.ParentId != null && !workGroups.Any(a => a.ParentId == w.Id)).ToList();