LINQ加入加入,怎么样?

时间:2011-02-24 19:44:32

标签: linq join linq-to-objects left-join

我是LINQ的新手。我正在使用LINQ to Objects(我认为)以及设置数据的方式我不能直接获取我需要的数据。 这是我需要做的一般结构:

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

我需要来自Process的单个数据 到目前为止,我已经找到了如何使用DefaultIfEmpty()使用LINQ进行LEFT OUTER JOIN,但我无法弄清楚如何使用ProjectStatus将Process转换为JOIN。 到目前为止,我有这个(ps是ProjectStatus):

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

但是这给了我一个关于“ps不在等于左边的范围内”的错误。

修改
为了便于参考,我所包含的“连接”不是整个语句。 “ProjectStatus”(ps)加入“Project”(pr),我也需要加入“Process”(ec)。
ec与pr没有任何关系,因此必须通过ps加入。 翻转“on”语句并不能解决问题。

编辑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 个答案:

答案 0 :(得分:1)

您只需翻转on声明

即可

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

关于多个连接,您应该能够链接它们

答案 1 :(得分:0)

您只需要交换ecps

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()

有多种方法可以命名对象,但我通常会发现我编写连接以进入具有可空前缀的对象名称,然后使用下一行from ec in nullablePsec.DefaultIfEmpty()

再次给它指定相同的名称

编辑:看到完整的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已将您在联接查询中使用的变量名称更改为进程列表。

编辑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()

答案 2 :(得分:0)

进行组连接时,内部序列中的变量超出范围,您无法再访问各个元素。如果您想要访问权限,则需要移动关联的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()
            // ...