带有关键字的连接表上的子句

时间:2013-05-07 16:23:33

标签: linq linq-to-entities

我希望在过滤其中一个表时加入两个表。这很好用

var matching = from a in ctx.A
               join b in ctx.B on a.BId equals b.Id
               where idList.Contains(b.Id)
               select a;

但是,如果我也使用into关键字命名连接结果

var matching = from a in ctx.A
               join b in ctx.B on a.BId equals b.Id into c
               where idList.Contains(b.Id)
               select a;

我收到编译错误告诉我

  

当前上下文中不存在名称“b”

但是,我可以在那时引用a,以及'c',没有问题。

为什么会这样,我如何将 where 子句应用于b

1 个答案:

答案 0 :(得分:4)

  

为什么这完全是

因为在join into子句之后,该子句引入的范围变量不在范围内 - 而以前的变量是。不要忘记您将加入 c,因此b的每个值实际上都是值组(c)的一部分。

  

如何将where子句应用于b?

早些时候这样做:

var matching = from a in ctx.A
               join b in ctx.B.Where(x => idList.Contains(x.Id))
                 on a.BId equals b.Id into c
               where c.Any()
               select a;

编辑:这可以放在稍微更多的面向查询表达式的代码中:

var matchingBs = from b in ctx.B
                 where idList.Contains(b.Id)
                 select b;
var matching = from a in ctx.A
               join b in matchingBs
                 on a.BId equals b.Id into c
               where c.Any()
               select a;

(你可以使用嵌套的查询表达式,但我并不热衷于那些。)

或在Any上使用c

var matching = from a in ctx.A
               join b in ctx.B on a.BId equals b.Id into c
               where c.Any(b => idList.Contains(b.Id))
               select a;

甚至:

var matching = from a in ctx.A
               where ctx.B.Any(b => idList.Contains(x.Id) &&
                                    a.BId == b.Id)
               select a;

可以改写为:

var matching = ctx.A.Where(a => ctx.B.Any(b => idList.Contains(x.Id) &&
                                          a.BId == b.Id));

了解joinjoin into之间结果的差异非常重要 - 第一个创建“成对”联接;第二个创建连接,其中额外范围变量的结果是一组匹配。