我一直在关注此网站上的一些示例,以了解如何创建Linq左外连接查询,但是我还没有找到“左连接中的外键未指向内键”的示例。而是指向上一个键”。请接受我的说法,我知道这是不正确的,但请看以下代码片段,也许会更清楚。
具体来说,请参见第一个左连接,其中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中)执行两个连续的左外部联接,但如何使用我的左联接中先前表之一的键?
我也不确定内/外键等的正确术语,因此措辞和标题很尴尬。也许有人可以纠正它,这样对他人会更有利。谢谢。
答案 0 :(得分:1)
您的LINQ翻译才刚刚结束。
SQL在crm.tbljobs
上具有内部联接,然后在common.tblSalesPerson
和common.tblSupervisors
上具有外部联接。
LINQ在dbc.tblJobs
和dbc.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()
...
我将temp1
和temp2
更改为更有意义的名称,以演示它们在外部联接语法中所代表的含义。请注意,例如dbc.tblSalesPersons
与salesPersons
的关系和相对位置。
要记住的另一件事是sp
和s
可以为null,因此请确保在访问它们的FirstName
,LastName
和{{ 1}}属性。