Linq加入缺少的列

时间:2017-01-11 23:01:13

标签: c# entity-framework linq select c#-4.0

我有两张桌子。

表A

TableAId value value2
 1        a     b
 2        aa    bb
 3        aaa   bbb

表B

TableBId TableAId  Status 
  1        1       success
  2        1       success
  3        2       failed
  4        2       failed

我正在尝试创建列表,如

   TableAId value value2 successCount errorCount
     1        a     b       2           0
     2        aa    bb      0           2
     3        aaa   bbb     0           2

这是我正在写的查询

from a in db.TableA
join b in db.TableB on a.TableAId equals b.TableAId
group b by a into g
select new
{
    TableAId = g.Key.TableAId,
    value = g.Key.value,
    value2 = g.Key.value2,
    successCount = g.Count(t => t.Status == "success"),
    errorCount = g.Count(t => t.Status == "failed")
}

从上面的查询我得到以下结果

  TableAId value value2 successCount errorCount
     1        a     b       2           0
     2        aa    bb      0           2

问题是我错过了表B中没有Hid记录的记录。在这种情况下,我缺少 TableAId:3记录

如何包含仅在表A中且在表B中没有任何记录的记录。

任何建议将不胜感激。 提前谢谢。

3 个答案:

答案 0 :(得分:2)

使用group join从tableB获取与tableA中的记录相关的记录(通过TableAId连接表)。然后只需从tableB记录组中选择计数:

from a in db.TableA
join b in db.TableB on a.TableAId equals b.TableAId into ab
select new {
    a.TableAId,
    a.value,
    a.value2,
    successCount = ab?.Count(t => t.Status == "success") ?? 0,
    errorCount = ab?.Count(t => t.Status == "failed") ?? 0
};

输出:

[
  {
    "TableAId": 1,
    "value": "a",
    "value2": "b",
    "successCount": 2,
    "errorCount": 0
  },
  {
    "TableAId": 2,
    "value": "aa",
    "value2": "bb",
    "successCount": 0,
    "errorCount": 2
  },
  {
    "TableAId": 3,
    "value": "aaa",
    "value2": "bbb",
    "successCount": 0,
    "errorCount": 0
  }
]

答案 1 :(得分:1)

你需要linq equivalent of a left outer join。 (另一个很好的例子是here

所以,例如:

from a in db.TableA
join b in db.TableB on a.TableAId equals b.TableAId into c
from d in c.DefaultIfEmpty()
group b by a into g
select new
{
    TableAId = g.Key.TableAId,
    value = g.Key.value,
    value2 = g.Key.value2,
    successCount = g.Count(t => t.Status == "success"),
    errorCount = g.Count(t => t.Status == "failed")
}

你可能需要在select new {...}部分添加一些额外的东西来处理successcount / errorcount的空值,我不确定,不是我现在可以测试的地方。

答案 2 :(得分:1)

您需要执行左连接并使用into / from / DefaultIfEmpty()

from a in db.TableA
join b in db.TableB on a.TableAId equals b.TableAId into bg
form b in bg.DefaultIfEmpty()
group b by a into g
select new
{
    TableAId = g.Key.TableAId,
    value = g.Key.value,
    value2 = g.Key.value2,
    successCount = g.Count(t => t.Status == "success"),
    errorCount = g.Count(t => t.Status == "failed")
}