.net Can';不要离开加入linq查询工作!

.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

我一直在看下面的帖子,并试图将其应用到我的帖子中,但运气不佳:

下面的查询每次运行时都返回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)

你的问题在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的声誉。