首页 文章

如何使用中间表进行Linq左外连接?

提问于
浏览
1

我一直在关注如何创建Linq Left Outer Join查询的本网站上的一些示例,但我没有找到任何“左连接中的外键不指向内键但是指向哪里”的示例以前的密钥“ . 跟我说这个措辞我知道这不正确,但看看下面的代码片段,也许它会更清楚 .

具体来说,请参见第一个左连接,其中sp.SalesPersonID = j.SalesPersonID .

select rt.Name as ResourceType, s.FirstName + ' ' + s.Surname as Supervisor, sp.FirstName + ' ' + sp.LastName as SalesPerson, tr.OrderCodeID, tr.SkillID
    , j.CustomerName, j.JobNumber
from dbo.TaskResource tr join projects.Task t on t.ID = tr.taskiD
    join dbo.ResourceType rt on rt.ID = tr.ResourceTypeID
    join projects.projecttask pt on pt.taskid = tr.taskid 
    join projects.jobproject jp on jp.projectid = pt.projectid 
    join crm.tbljobs j on j.jobid = jp.jobid 
    left join common.tblSalesPersons sp on sp.SalesPersonID = j.SalesPersonID
    left join common.tblSupervisors s on s.SupervisorID = j.SupervisorID
where JobDeleted is null or JobDeleted = 0
order by ResourceType

当转换为Linq时,它会成功

...from j in temp1.DefaultIfEmpty()
    join sp in dbc.tblSalesPersons on j.SalesPersonID equals sp.SalesPersonID into temp2

到现在为止还挺好 . 但是,当我做下一个左连接时,虽然它只是相同的东西,但指向前面提到的一个先前的键,所以不使用我见过几个例子的 sp 变量,我使用 j 变量来自之前的加入:

from sp in temp2.DefaultIfEmpty()
    join s in dbc.tblSupervisors on j.SupervisorID equals s.SupervisorID

以下是完整的代码段:

List<ResourceTreeObject> resourceTreeObjects = (
                from tr in dbc.TaskResources
                join t in dbc.Tasks on tr.TaskID equals t.ID
                join rt in dbc.ResourceTypes on tr.ResourceTypeID equals rt.ID
                join pt in dbc.ProjectTasks on tr.TaskID equals pt.TaskID
                join jp in dbc.JobProjects on pt.ProjectID equals jp.ProjectID
                join j in dbc.tblJobs on jp.JobID equals j.JobID into temp1
                from j in temp1.DefaultIfEmpty()
                join sp in dbc.tblSalesPersons on j.SalesPersonID equals sp.SalesPersonID into temp2
                from sp in temp2.DefaultIfEmpty()
                join s in dbc.tblSupervisors on j.SupervisorID equals s.SupervisorID
                where j.JobDeleted == null || j.JobDeleted == 0
                select new ResourceTreeObject
                {
                    TaskResourceID = tr.ID
                    ,
                    TaskID = tr.TaskID
                    ,
                    ResourceTypeID = tr.ResourceTypeID
                    ,
                    ResourceType = rt.Name
                    ,
                    SkillID = tr.SkillID
                    ,
                    OrderCodeID = tr.OrderCodeID
                    ,
                    PermissionID = tr.PermissionID
                    ,
                    JobID = j.JobID
                    ,
                    JobNumber = j.JobNumber
                    ,
                    CustomerName = j.CustomerName
                    ,
                    Salesperson = sp.FirstName + " "  + sp.LastName
                    ,
                    Supervisor = s.FirstName + " " + s.Surname

                }).ToList();

这会导致错误的查询 . 最后一个“左连接”被视为内连接并返回错误的行数 . 所以本质上我要问的是,在执行几个连续的内连接之后,我如何(在LinQ中)做两个连续的左外连接,但是使用我左边连接中前面一个表中的一个键?

另外我不确定内/外键等的正确术语是什么,因此尴尬的措辞和 Headers . 也许有人可以纠正这一点,这样对其他人来说会更有利 . 谢谢 .

1 回答

  • 1

    你的LINQ翻译只是一点点 .

    SQL在 crm.tbljobs 上有一个内连接,后跟 common.tblSalesPersoncommon.tblSupervisors 上的外连接 .

    LINQ在 dbc.tblJobsdbc.tblSalesPersons 上有外连接,后跟 dbc.tblSupervisors 上的内连接 .

    into temp1 ... from j in in temp1.DefaultIfEmpty() 使外连接发生在 into 之前引入的表上,即 dbc.tblJobs .

    所以它应该是:

    ...
    // inner join
    join j in dbc.tblJobs on jp.JobID equals j.JobID
    
    // left outer join
    join sp in dbc.tblSalesPersons on j.SalesPersonID equals sp.SalesPersonID into salesPersons
    from sp in salesPersons.DefaultIfEmpty()
    
    // left outer join
    join s in dbc.tblSupervisors on j.SupervisorID equals s.SupervisorID into supervisors
    from s in supervisors.DefaultIfEmpty()
    ...
    

    我将 temp1temp2 更改为更有意义的名称,以演示它们在外连接语法中的表示 . 例如,注意 dbc.tblSalesPersonssalesPersons 的关系和相对位置 .

    还有一件事需要记住, sps 可以为null,因此请确保在访问它们的 FirstNameLastNameSurname 属性之前检查它 .

相关问题