0

テーブルの 1 つをフィ​​ルタリングしながら、2 つのテーブルを結合したいと考えています。それはうまくいきます

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。最初は「ペアワイズ」結合を作成します。2 番目は、追加の範囲変数の結果が一致のグループであるグループ結合を作成します。

于 2013-05-07T16:28:56.307 に答える