BT

LINQ to Entitiesが直前のクエリーによって返す結果が違うって本当?

| 作者: Jonathan Allen フォローする 597 人のフォロワー , 翻訳者 菅野 裕 フォローする 0 人のフォロワー 投稿日 2008年12月9日. 推定読書時間: 2 分 |

Stu Smith氏は自身のブログの最近の記事で、「LINQ to Entitiesは直前に実行したクエリーによって異なる結果を返すぞ(リンク)」と主張した。もしそれが本当なら、Entity Frameworkは利用するにはとても難しいものになる。私たちはADO.NETチームのElisa Flasko氏に事の真相について尋ねた。

このケースは実のところ著者の誤解です。著者が実行した2つ目のクエリー、var orderは実際にはLINQ to Objectsクエリーであって、LINQ to Entities(もしくはLINQ to SQL)クエリーではありません。LINQ to Objectsクエリーは最初のクエリー、すなわちvar aliceでメモリーに取り込んだデータに対して問い合わせを行っているのです。

結果が異なる理由は、LINQ to SQLが遅延ロードをサポートしているのに対し、Entity Frameworkのバージョン1はサポートしていないからです。最初のクエリーについては、著者はcustomerエンティティだけをメモリーに取ってきています(これはLINQ to SQLもLINQ to ENtitiesも同じです)。しかし2つ目のクエリー(orders)では、著者は関連するOrdersエンティティへのアクセスを試みています。ここで遅延ロードならデータベースに情報を取り出すために2回目のアクセスをするのですが、Entity Frameworkの明示的なローディングでは、特別にデータベースへ「魔法のように」アクセスすることはありません。Ordersはメモリーには存在せず、LINQ to ObjectsクエリーをLINQ to Entitiesの結果にかぶせても、Ordersは取得できないのです。一方、foreachをOrdersにかけた後では(著者ははっきり data.Ordersを呼ぶことで、コンテキストにアクセスし、データベースのすべてのOrdersに問い合わせをかけています)、Ordersはメモリーに置かれ、そのためLINQ to Objectsがそれらに問い合わせることができたのです。

実を言うと、私たちはEntity FrameworkのV2で遅延ロードを利用できるようにしています。とはいえ、デフォルトで遅延ロードがオフになっているのは変わりません。その理由は、開発者がデータベースをN+1回検索してしまう性能問題にうっかりはまってしまわないことを確実にするためです。N+1問題は遅延ロードでは簡単に起きてしまいます。それよりは、明示的にフレームワークに伝えることで、開発者が遅延ロードによる性能問題に気を遣わせない方を選びました。

さて、これは重要な設計の問題だろうか?それとも単なるトレーニングの問題だろうか?

 

原文はこちらです:http://www.infoq.com/news/2008/12/Lazy-Loading

この記事に星をつける

おすすめ度
スタイル

こんにちは

コメントするには InfoQアカウントの登録 または が必要です。InfoQ に登録するとさまざまなことができます。

アカウント登録をしてInfoQをお楽しみください。

あなたの意見をお聞かせください。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする
コミュニティコメント

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

ディスカッション

InfoQにログインし新機能を利用する


パスワードを忘れた方はこちらへ

Follow

お気に入りのトピックや著者をフォローする

業界やサイト内で一番重要な見出しを閲覧する

Like

より多いシグナル、より少ないノイズ

お気に入りのトピックと著者を選択して自分のフィードを作る

Notifications

最新情報をすぐ手に入れるようにしよう

通知設定をして、お気に入りコンテンツを見逃さないようにしよう!

BT