1

我在sqlServer中有3个表如下:

Cost_Types

Id   COST_NAME
-------------
1      A
2      B
3      C
4      D
5      E
6      F
7      Z

和请求表

Id   No
----------
1     100
2     200
3     300

和 Cost_Request (=clearance_cost)

RequestId     CostId   Amount
-------------------------------
1               2       200
1               3       400

我想得到这个结果

RequestId     CostId   Amount
    -------------------------------
    1               2       200
    1               3       400
    1               1        0
    1               4        0
    1               5        0
    1               6        0

我写这段代码

var context = new CLEARANCEEntities();
        var items = (from c in context.COST_TYPES
                     join t in context.CLEARANCE_COST
                         on c.COST_ID equals t.COST_ID into outer
                     from t in outer.DefaultIfEmpty()
                     where t. RequestId==1
                     select new
                          {
                            c.COST_ID,
                            c.COST_NAME, I = ((t == null) ? 0 : t.COST_AMOUNT)
                          }).ToList();

这段代码只返回这个

    RequestId     CostId   Amount
    -------------------------------
    1               2       200
    1               3       400

我想如果改变查询如下:

var context = new CLEARANCEEntities();
            var items = (from c in context.COST_TYPES
                         join t in context.CLEARANCE_COST
                             on c.COST_ID equals t.COST_ID into outer
                         from t in outer.DefaultIfEmpty()
                         where t.RequestId==2               
                         select new
                                    {
                                        c.COST_ID,
                                        c.COST_NAME, I = ((t == null) ? 0 : t.COST_AMOUNT)
                                    }).ToList();

返回此数据

 RequestId     CostId   Amount
    -------------------------------
    2               1      0
    2               2      0
    2               3      0
    2               4      0
    2               5      0
    2               6      0

请帮我。谢谢大家

4

3 回答 3

5

我知道 LEFT JOIN'ing 的 GroupJoin->SelectMany->DefaultIfEmpty 技术很流行......但我认为 SelectMany->NavigationPropertyJoin->DefaultIfEmpty 技术更清晰。

var query =
  from c in context.CostTypes
  from xr in c.CostRequests
    .Where(xrRecord => xrRecord.RequestId == 1)
    .DefaultIfEmpty()
  select new {
    CostType = c,
    Amount = xr == null ? 0 : xr.Amount
  }
于 2012-05-27T17:06:06.500 回答
2

对问题的不同理解后完全修改答案:

新答案

尝试将您的 WHERE 条件移动到 JOIN 子句。

您没有进行内部联接 - 因此联接的条件在这里是可以的,并且当您有匹配项时不会消除您的空值。但是,如果您将 t.RequestId==whatever 放在 where 子句中,您只需将它们过滤掉。

OLD ANSWER -INCORRECT- ANSWERED WRONG QUESTION 看起来 CostId 和 RequestId 在插入到 Cost_Request 表时已被交换,因此您正在进行左连接并加入 c.COST_ID 等于 t.COST_ID 但 t.COST_ID 确实包含 RequestId 在表中的实际数据。这将完全解释您所看到的结果集。要测试这个理论,请将您的加入更改为

c.COST_ID equals t.REQUEST_ID 

看看你是否得到你期望的结果。虽然没有看到您的实体模型这很难,因为提供的查询与提供的表中的名称不匹配,我正在做一些猜测。

于 2012-05-27T13:43:08.213 回答
1

对我来说,您似乎正在使用该where t == 1语句过滤掉所有其他行。我不确定t在那个阶段你可以过滤什么 - 它似乎对应于 clearence_cost.request_id。

您是否尝试过不带该where子句的查询?

此外,您在 select 语句中的内容非常令人困惑:

 select new
         {
            c.COST_ID,
            c.COST_NAME, 
            I = ((t == null) ? 0 : t.COST_AMOUNT)
          }

查看“预期”结果集,似乎 c.Cost_id == requestId ?, c.CostName == cost_id ?Cost_name 到底是什么?

老实说,如果您想解决这个问题,您必须先投入一些时间并整理帖子中的烂摊子。你不能指望人们猜到为什么名字不同,并且神奇地知道你的意思。

于 2012-05-27T14:38:40.770 回答