0

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

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

4

1 回答 1

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;

(您可以使用嵌套查询表达式,但我一般不喜欢那些。)

或使用Anyon 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));

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

于 2013-05-07T16:28:56.307 回答