I've been looking at the following post and trying to apply it to mine but with no luck: LINQ Inner-Join vs Left-Join
I have the query below that returns 0 records everytime I run it:
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)
};
Where luProjectTaskTypes
is a lookup table that has a list of options. I want one record returned for each entry in this table regardless of whether it has a match in CostByTasks
but I always get 0. What am I doing wrong?!
UPDATE:
This is the SQL it is generating-
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)
Not sure if this'll help, but you could try moving your where clause into the 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)
};
You would need to worry about checking for cbt.ProposalID == null
and It should produce this sql instead -
... FROM [frgprop].[luProjectTaskType] AS [t0]
LEFT OUTER JOIN [frgprop].[CostByTask] AS [t1] ON [t0].[ProjectTaskTypeID] = [t1].[ProjectTaskTypeID] AND [t1].[ProposalID] = @p0
UPDATE: Below is the updated version that compiles. A few minor changes got it working.
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)
};
Your problem is in the WHERE clause
When you LEFT JOIN a table, that's fine, but if you set criteria on the LEFT-JOINED table, it basically turns it into an INNER JOIN. You should allow for Nulls to get past this.
where cbt.ProposalID == Convert.ToInt32(this.StateItems["PropNumber"]) OR cbt.ProposalID is NULL
I'm not sure how about the is NULL syntax -- maybe have to be db.null(field)
, etc. -- you'll have to check on that; but the concept is valid.
精彩评论