我一直在看以下帖子并试图将它应用到我的但没有运气: LINQ Inner-Join vs Left-Join
我有下面的查询,每次运行它都会返回0条记录:
var tasks = from tt in d.luProjectTaskTypes
join cbt in d.CostByTasks
on tt.ProjectTaskTypeID equals cbt.ProjectTaskTypeID into temp
from cbt in temp.DefaultIfEmpty()
where cbt.ProposalID == Convert.ToInt32(this.StateItems["PropNumber"]) || cbt.ProposalID == null
select new
{
ProposalId = (cbt.ProposalID == null ? Convert.ToInt32(this.StateItems["PropNumber"]) : cbt.ProposalID),
TaskId = tt.ProjectTaskTypeID,
CostByTaskId = (cbt.CostByTaskID == null ? 0 : cbt.CostByTaskID),
TypeOfWork = tt.ProjectTaskType,
AmountRequested = (cbt.AmountRequested == null ? 0 : cbt.AmountRequested),
CostShare = (cbt.CostShareAmount == null ? 0 : cbt.CostShareAmount)
};
其中luProjectTaskTypes
是包含选项列表的查找表。我希望为此表中的每个条目返回一条记录,无论它是否在CostByTasks
中匹配,但我总是得到0.我做错了什么?!
更新
这是它正在生成的SQL -
SELECT
(CASE
WHEN ([t1].[ProposalID]) IS NULL THEN @p1
ELSE [t1].[ProposalID]
END) AS [ProposalId], [t0].[ProjectTaskTypeID] AS [TaskId],
(CASE
WHEN ([t1].[CostByTaskID]) IS NULL THEN @p2
ELSE [t1].[CostByTaskID]
END) AS [CostByTaskId], [t0].[ProjectTaskType] AS [TypeOfWork],
(CASE
WHEN [t1].[AmountRequested] IS NULL THEN CONVERT(Decimal(33,4),@p3)
ELSE CONVERT(Decimal(33,4),[t1].[AmountRequested])
END) AS [AmountRequested],
(CASE
WHEN [t1].[CostShareAmount] IS NULL THEN CONVERT(Decimal(33,4),@p4)
ELSE CONVERT(Decimal(33,4),[t1].[CostShareAmount])
END) AS [CostShare]
FROM [frgprop].[luProjectTaskType] AS [t0]
LEFT OUTER JOIN [frgprop].[CostByTask] AS [t1] ON [t0].[ProjectTaskTypeID] = [t1].[ProjectTaskTypeID]
WHERE ([t1].[ProposalID] = @p0) OR (([t1].[ProposalID]) IS NULL)
答案 0 :(得分:2)
您的问题出在WHERE子句
中当你LEFT JOIN一个表时,没关系,但是如果你在LEFT-JOINED表上设置标准,它基本上把它变成一个INNER JOIN。你应该允许Null通过它。
where cbt.ProposalID == Convert.ToInt32(this.StateItems["PropNumber"]) OR cbt.ProposalID is NULL
我不确定is NULL语法怎么样 - 可能必须是db.null(field)
等等 - 你必须检查一下;但这个概念是有效的。
答案 1 :(得分:2)
不确定这是否有帮助,但您可以尝试将where子句移动到连接中 -
var tasks = from tt in d.luProjectTaskTypes
join cbt in d.CostByTasks
on new {ptid = tt.ProjectTaskTypeID, pid = cbt.ProposalID } equals new { ptid = cbt.ProjectTaskTypeID, pid = Convert.ToInt32(this.StateItems["PropNumber"] } into temp
from cbt in temp.DefaultIfEmpty()
select new
{
ProposalId = (cbt.ProposalID == null ? Convert.ToInt32(this.StateItems["PropNumber"]) : cbt.ProposalID),
TaskId = tt.ProjectTaskTypeID,
CostByTaskId = (cbt.CostByTaskID == null ? 0 : cbt.CostByTaskID),
TypeOfWork = tt.ProjectTaskType,
AmountRequested = (cbt.AmountRequested == null ? 0 : cbt.AmountRequested),
CostShare = (cbt.CostShareAmount == null ? 0 : cbt.CostShareAmount)
};
你需要担心检查cbt.ProposalID == null
而它应该生成这个sql -
... FROM [frgprop].[luProjectTaskType] AS [t0]
LEFT OUTER JOIN [frgprop].[CostByTask] AS [t1] ON [t0].[ProjectTaskTypeID] = [t1].[ProjectTaskTypeID] AND [t1].[ProposalID] = @p0
<强>更新强> 以下是编译的更新版本。一些小的改变让它发挥作用。
var tasks = from tt in d.luProjectTaskTypes
join cbt in d.CostByTasks
on new {tt.ProjectTaskTypeID, ProposalID = Convert.ToInt32(this.StateItems["PropNumber"]) } equals new {cbt.ProjectTaskTypeID, cbt.ProposalID} into temp
from cbt in temp.DefaultIfEmpty()
select new
{
ProposalId = (cbt.ProposalID == null ? Convert.ToInt32(this.StateItems["PropNumber"]) : cbt.ProposalID),
TaskId = tt.ProjectTaskTypeID,
CostByTaskId = (cbt.CostByTaskID == null ? 0 : cbt.CostByTaskID),
TypeOfWork = tt.ProjectTaskType,
AmountRequested = (cbt.AmountRequested == null ? 0 : cbt.AmountRequested),
CostShare = (cbt.CostShareAmount == null ? 0 : cbt.CostShareAmount)
};