2011-02-07 5 views
3

私はEF4を使用してASP.NET 4 Webアプリケーションを構築していると私はこのようなテーブルがある:EF4遅い連想アクセス

製品
属性

Product_Attribute_Map

Product_Attribute_Mapですクロステーブル、多対多。したがって、Productは0または多くのAttributeを持つことができ、その逆もあります。コードで

私はこれを行う:

//Attribute a = new Attribute(); // Edit: 
Attribute a = (from a in context.Attributes where a.AttributeID = 1 select a).First(); 
a.Name = "test"; 
Product.Attributes.Add(a); 

が、私はこれが非常に遅くなり、問題に気づきました。 EF4はサーバー上でこのSQLを実行します。

SELECT 
[Extent2].* FROM [dbo].[Product_Attribute_Map] AS [Extent1] 
INNER JOIN [dbo].[Product] AS [Extent2] ON [Extent1].[ProductID] = [Extent2].[ProductID] 
WHERE [Extent1].[AttributeID] = @p1 

これはなぜこのようなことがわかりません。 10.000プロダクトにアトリビュートを割り当てると、これが悪いクエリになります。製品に属性を追加するのに5秒以上かかります...

どのようにしてEF4がすべての属性を選択するのを防ぐことができますか?そして、この製品の属性を選択するだけです。

ありがとう

編集:これはPOCO t4テンプレートのみを使用しています。 EntityObjectテンプレートにこの問題はありません。

+0

EFがあなたの属性に 'Products'コレクションを移そうとしているようです。あなたのテーブルマッピングはどのように見えますか? – StriplingWarrior

+0

遅延ロードがオンになっていますか?あなたはここでそれが欲しくないかもしれません。表示されたコードは役に立ちません。それなしで試してみてください。 –

+0

遅延ロードがオンになっているため、SQLクエリが実行されています。オフにすると、他の既存のマッピングが保存時に削除されます(コレクションに含まれていないため) – peter

答えて

1

私の推測:これは、POCOテンプレートによって生成されたFixUpCollectionsと共に使用されるLazyLoadingのために発生します。製品に属性を追加すると、フィックスアップコレクションも逆の操作を実行します。属性にprductが追加されますが、属性の製品コレクションに最初にアクセスすると遅延読み込みが発生し、クエリが実行されます。フィックスアップコレクションが好きではありません... POCOテンプレートを使用しないように変更することもできますし、Attribute内のProductsナビゲーションプロパティを削除することもできます(必要がない場合)。

+0

フィックスアップ操作を削除することの欠点を知っていますか? – peter

+0

@peter:関係の双方向同期が失われます。あなたのコードはそれらに依存する必要はありません。製品に属性を追加し、変更を保存する前に逆方向を使用する場合は、属性に製品を手動で追加する必要があります。 FixUpコレクションを使用しない独自のPOCOエンティティ(コード内で共通)を定義することができます。 –

+0

フィックスアップメソッドを削除しても、残念ながら問題は解決されませんでした。しかし、AttributeからProductsナビゲーションプロパティを削除する際のヒントは、より速くなります。私はそれをこのように保つと思います。しかし、EntityObject T4にはなぜこの問題がないのですか? – peter