LINQ Присоединиться внутри Присоединиться, как? - PullRequest
0 голосов
/ 24 февраля 2011

Я новичок в LINQ.Я использую LINQ to Objects (я думаю) и способ настройки данных, я не могу напрямую получить нужную часть данных.Это общая структура того, что мне НУЖНО сделать:

FROM Project
    LEFT OUTER JOIN TechnologySectors
    LEFT OUTER JOIN SelectedAgencies
    LEFT OUTER JOIN ProjectStatus
        JOIN Process

Мне нужен один фрагмент данных из Process.
До сих пор я выяснил, как сделать LEFT OUTER JOIN с LINQ, используяDefaultIfEmpty(), но я не могу понять, чтобы получить Process для JOIN с ProjectStatus.
Пока у меня есть это (ps is ProjectStatus):

join ec in this._Process.GetProcessList() on ps.ProcessID equals ec.ProcessID into psec

, но это дает мне ошибку о "ps notв области на левой стороне равно ".

РЕДАКТИРОВАТЬ
Для справки, "соединение", которое я включил, не является полным утверждением.«ProjectStatus» (ps) присоединяется к «Project» (pr), и мне нужно также присоединить «Process» (ec).
ec не имеет никакого отношения напрямую к pr, и поэтому его необходимо соединить через ps.Переключение операторов on не решает проблему.

EDIT 2
Полный запрос LINQ:

from pr in this._projectRepo.GetAllProjects()
join tr in this._techRepo.GetTechnologySectors() on pr.TechnologySectorID equals tr.TechnologySectorID into prtr
join ev in this._ecEnvRepo.GetAllSelectedAgencies() on pr.ID equals ev.ID into prev
join ps in this._ecProjectStatRepo.GetAllECProjectStatus() on pr.ID equals ps.ID into prps
***THIS LINE***join ec in this._ecProcessRepo.GetProcessList() on ps.ProcessID equals ec.ProcessID into psec
from tr in prtr.DefaultIfEmpty()
from ev in prev.DefaultIfEmpty()
from ps in prps.DefaultIfEmpty()
from ec in psec.DefaultIfEmpty()

Это не работает.
Я также пытался извлечь эту строку и просто использовать это:

from ec in this._ecProcessRepo.GetProcessList() where (ec.ProcessID == ps.ProcessID)

И я попытался использовать это вместо строк ps и ec:

from ps in this._ecProjectStatRepo.GetAllECProjectStatus() where (ps.ID == pr.ID)
join ec in this._ecProcessRepo.GetProcessList() on ps.ProcessID equals ec.ProcessID into psec
from ec in psec.DefaultIfEmpty()

Ответы [ 3 ]

1 голос
/ 24 февраля 2011

Вам просто нужно перевернуть оператор on

join ec in this._Process.GetProcessList() on ec.ProcessID equals ps.ProcessID into psec

Что касается множественных объединений, вы должны иметь возможность их связывать

0 голосов
/ 24 февраля 2011

Когда вы выполняете групповое соединение, переменная из внутренней последовательности выходит из области видимости, и у вас больше нет доступа к отдельным элементам.Вам нужно переместить связанный DefaultIfEmpty() вверх, если вы хотите получить доступ или не хотите присоединяться к группе.

var query = from pr in this._projectRepo.GetAllProjects()
            join tr in this._techRepo.GetTechnologySectors()
                on pr.TechnologySectorID equals tr.TechnologySectorID
                into prtr
            join ev in this._ecEnvRepo.GetAllSelectedAgencies()
                on pr.ID equals ev.ID
                into prev
            join ps in this._ecProjectStatRepo.GetAllECProjectStatus()
                on pr.ID equals ps.ID
                 into prps
            from ps in prps.DefaultIfEmpty()
            // you need to resolve `ps == null` issues here
            let key = ps == null ? -1 : ps.ProcessID
            join ec in this._ecProcessRepo.GetProcessList()
                on key equals ec.ProcessID
                into psec
            from tr in prtr.DefaultIfEmpty()
            from ev in prev.DefaultIfEmpty()
            from ec in psec.DefaultIfEmpty()
            // ...
0 голосов
/ 24 февраля 2011

Вам просто нужно поменять ec и ps на

ec in this._Process.GetProcessList() on 
    ps.ProcessID equals ec.ProcessID into psec

. Чтобы выполнить левое объединение, вам необходимо выполнить следующие действия:

ec in this._Process.GetProcessList() on 
    ps.ProcessID equals ec.ProcessID into nullablePsec
from ec in nullablePsec.DefaultIfEmpty()

. Существуют различные способы.чтобы назвать объекты, но я обычно нахожу, что я пишу объединение, чтобы войти в имя объекта с префиксом nullable, а затем снова дать ему то же имя, используя следующую строку from ec in nullablePsec.DefaultIfEmpty()

EDIT : После просмотра полного запроса linq вам нужно присоединиться следующим образом

ec in this._Process.GetProcessList() on 
    prps.ProcessID equals ec.ProcessID into psec

Обратите внимание, что объединение происходит по имени переменной prps, когда вы выбираете для prps в строке над ним

join ps in this._ecProjectStatRepo.GetAllECProjectStatus() on pr.ID equals ps.ID into prps

into prps изменил имя переменной, с которой вы будете работать в запросе соединения, на список процессов.

EDIT 2 Возможно, вам будет немного лучшенаписать заявление следующим образом

from pr in this._projectRepo.GetAllProjects()
join tr in this._techRepo.GetTechnologySectors() on pr.TechnologySectorID equals tr.TechnologySectorID into prtr
from tr in prtr.DefaultIfEmpty()
join ev in this._ecEnvRepo.GetAllSelectedAgencies() on pr.ID equals ev.ID into prev
from ev in prev.DefaultIfEmpty()
join ps in this._ecProjectStatRepo.GetAllECProjectStatus() on pr.ID equals ps.ID into prps
from ps in prps.DefaultIfEmpty()
join ec in this._ecProcessRepo.GetProcessList() on ps.ProcessID equals ec.ProcessID into psec
from ec in psec.DefaultIfEmpty()
...