8

SelectManyLINQPad で生成された SQL を使用してクエリを作成し、チェックしています。クエリは非常に単純です。

、、、という 3 つのエンティティがCustomerあるOrderとしOrderItemます。OrderItem注文された製品と数量に関する情報を保持します。

OrderItems一人のお客様のためにすべてを手に入れたい。

context.Customers.First().Orders.SelectMany(o=>o.OrderItems)

期待どおりの結果セットが得られますが、SQL は私にとって本当に奇妙です。選択ステートメントがたくさんあります。最初に 1 人の顧客を選択しますが、これで問題ありません。OrderItem次に、1 つの Order を選択し (この顧客には 1 つしかないため)、以前に選択したものごとに 1 つの選択を作成しOrderます。したがって、次のようになります。OrderItemsOrdersCustomer

select top 1 from Customers;

select * from Orders where CustomerID = @cID;

select * from OrderItems where OrderID = @o1;
select * from OrderItems where OrderID = @o2;
select * from OrderItems where OrderID = @o3;
select * from OrderItems where OrderID = @o4;

私が期待するのは次のようなものです:

select oi.* 
from OrderItems oi
join Orders o on o.OrderID = oi.OrderId
join Customers c on c.CustomerID = o.CustomerID
where c.CustomerID = @someID

ワンセレクト、素敵できれい。

本当にそのように機能しますかSelectMany、それとも何か間違ったことをしているのですか、それとも私のモデルに何か問題があるのでしょうか? SelectManyそのような単純なものを SQL に変換する方法の例はどこにも見つかりません。

これは少数の場合は問題ではありませんが、顧客がそれぞれ 200 の注文アイテムで 100 の注文を行う場合、20,000 の選択があります...

4

1 に答える 1

9

クエリには次を使用する必要があります (特定の顧客の注文項目を でクエリするにはsomeId)。

context.Customers.Where(c => c.Id == someId)
    .SelectMany(c => c.Orders.SelectMany(o => o.OrderItems))

または - の動作を再現するにはFirst()、単一の DB クエリを使用します。

context.Customers.Take(1)
    .SelectMany(c => c.Orders.SelectMany(o => o.OrderItems))

元のクエリがFirst(クエリ 1) で顧客を読み込み、次に遅延読み込みがその顧客のOrdersコレクションを読み込み (クエリ 2)、次に遅延読み込みが読み込まれた各項目のコレクションを再度Order読み込みます(クエリ 3 から n)。これらの複数のクエリをすべて回避するには、クエリ式内でFirst()やなどの「クエリ実行メソッド」を使用しないでください。ToList()

于 2012-12-05T13:30:35.917 に答える