.net Can';不要离开加入linq查询工作!
我一直在看下面的帖子,并试图将其应用到我的帖子中,但运气不佳: 下面的查询每次运行时都返回0条记录:.net Can';不要离开加入linq查询工作!,.net,linq,linq-to-sql,.net,Linq,Linq To Sql,我一直在看下面的帖子,并试图将其应用到我的帖子中,但运气不佳: 下面的查询每次运行时都返回0条记录: var tasks = from tt in d.luProjectTaskTypes join cbt in d.CostByTasks on tt.ProjectTaskTypeID equals cbt.ProjectTaskTypeID into temp
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)
你的问题在WHERE子句中 当您左键联接一个表时,这很好,但是如果您在左键联接的表上设置条件,它基本上会将其变成一个内部联接。您应该允许空值通过此设置
where cbt.ProposalID == Convert.ToInt32(this.StateItems["PropNumber"]) OR cbt.ProposalID is NULL
我不确定is-NULL语法如何——可能必须是
db.NULL(field)
,等等——您必须检查一下;但是这个概念是有效的。不确定这是否有用,但是您可以尝试将where子句移动到join-
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)
};
生成的SQL看起来像什么?正如您所看到的,它肯定是在生成一个左连接。。。因此,我建议您开始攻击SQL本身,直到它生成您想要的内容,然后尝试将其转换回LINQ。此外--您需要将其转换回左连接。我假设您的意思是添加
|cbt.ProposalID==null
。我这样做了,但仍然没有记录。我已经更新了我的LINQ查询以反映此更改,这就是您的意思吗?请注意,一种更简单的方法是将where子句放入联接中:“from cbt in d.CostByTasks.where(x=>x.ProposalId==…)”Arg。。。是的,我就是这个意思。我经常在常规SQL查询中看到这个问题。好的,还在看。我想我下一步应该尝试删除WHERE子句,看看您的左连接是否正常工作--至少这有助于缩小范围。我还建议您做一个响应。在您的this.StateItems[“PropNumber”]上写下,只是为了确保你认为存在的价值真的存在…看起来你的想法是正确的,但它并没有完全编译。我继续写了一篇我自己的文章,为未来的用户做了一些修改。没关系,只要让我知道编译错误在哪里,我就可以在这里修复它,这样就不会有重复的答案,正确的答案就会得到认可。我不打算检查编译错误,因为设置类型对我来说太过分了。或者你甚至可以自己编辑它,因为你有超过2000的声誉。