2012-05-08 24 views
1

私はもう一度パフォーマンスをテストしています。データベースから簡単な結果を得たいだけです。Entity Frameworkがテーブルを結合しないようにするにはどうすればよいですか?

var jobsList = from j in mf.Jobs 
         where j.UserID == 1001 select new { Job = j }; 

これは、残念ながら私はEFがやりたくない、このリストに私のUserオブジェクトを結合します。関係があるからといってEFに参加しないように指示するにはどうすればいいですか?基本的には、そのテーブルから単純な行が必要です。

また、別の種類の検索を使用する必要がありますか。私はまだ以下のデータベース検索の基本的なタイプを使用していますが、今はDBの作業をよりうまく処理する方法があると感じています。私はより明確な文脈で言って基本的にはどのような

SqlConnection myconnection = new SqlConnection(); 

編集

。それだけではなく、次のことを得ることです。

Job.JobID 
Job.UserID 
//Extra properties 

私は、ユーザーオブジェクトを簡単に必要とされるよりも道多くのメモリを消費し、プラス私はそれを必要としないこと

Job.JobID 
Job.UserID 
Job.User 
//Extra properties 

を取得します。

マイソリューション

だから私はまだあまりEFを信じ、ここ理由であるわけではありません。私はLazyLoadingをオフにしてそれをオンにして、あまりパフォーマンスの違いがあまり気づかなかった。次に、SqlConnection型のメソッドが使用するデータの量を、EFのメソッドと比較して比較しました。

全く同じ結果セットが返されますが、ここではパフォーマンスの違いがあります。

私のEntity Frameworkメソッドでは、仕事のリストを取得します。

MyDataEntities mf = new MyDataEntities(); // 4MB for the connection...really? 
mf.ContextOptions.LazyLoadingEnabled = false; 
// 9MB for the list below 
var test = from j in mf.Jobs 
      where j.UserID == 1031 
      select j; 
foreach (Job job in test) { 
    Console.WriteLine(job.JobID); 
} 

私のSqlConnectionメソッドでは、ストアドプロシージャを実行し、結果セットを返します。

//356 KB for the connection and the EXACT same list. 
List<MyCustomDataSource.Jobs> myJobs = MyCustomDataSource.Jobs.GetJobs(1031); 

は、私は完全にEntity Frameworkのは仕方標準SqlConnectionのより多くの方法をやっていることを理解し、なぜ結果セットの25倍以上のメモリの最小で取るために起こっている場合は、このすべての誇大宣伝。ちょうど価値があるとは思われません。

結局のところ、私の解決策はEFと一緒に行かないことです。

+0

生成されたSQLの外観はどうですか? – Magnus

+3

遅延読み込みが有効になっていますか?そうでない場合は、Userプロパティを熱心に読み込んでいるために結合が行われている可能性があります。 –

+0

「これは残念ながら私のUserオブジェクトをこのリストに結合する」という意味ですか? – JotaBe

答えて

1

プロパティはジョブクラスの一部ですが、アクセスするまでは読み込まれません(遅延読み込み)。したがって、実際には「参加」されていません。

あなたは2つのだけ指定した列をしたい場合は、

var jobsList = from j in mf.Jobs 
       where j.UserID == 1001 
       select new { 
          Job.JobID, 
          Job.UserID 
          }; 
+0

これは私が必要としていると思います。基本的に、特定のクラスとそのクラスのみ、またはこの場合はテーブルを返す場合は、フィールドごとに指定する必要があります。 – meanbunny

+1

@meanbunnyテーブルジョブのすべての値を返す場合は、 '... select job'と書いてください。関連テーブルはオブジェクトに表示されますが、ロードされることはありません。 – Magnus

+0

ああ、私は今参照してください。これをテストした後、それは完璧な意味を持ちます。あなたの助けのためにTy。 – meanbunny

0

EFはあなたが1つの結果しか望んでいないと思っています。このようなことを試してみてください。

Job jobsItem = mf.Jobs.Single(j=>j.UserID==1001) 

あなたがlambasを使用しない場合は...

Job JobItem = (from j in mf.Jobs where j.UserID == 1001 select j).Single() 

私は今、近くのコンパイラを持っていない、私は、構文が正しいことを願っています。変数にJobの代わりにvarを使用することができます。これは何の効果もありませんが、私はJobがこの場合より読みやすくなっていると思います。

+0

私は構文がここで完璧だと思います。しかし、私の編集をチェックアウトし、私が何を言っているかについてもっと見る。最初は不完全な説明を残念に思っています。基本的に私は、UserIDとUserではなくUserIDを元に戻したいと考えています。 – meanbunny

+0

Ok:Dあなたの編集を読んだことがあります。それでは、それは怠惰なローディングの概念だと思う。 Jotaのようにそれを見てみましょう。 – Jonathan

1

を書くことができ、この動作のための最も可能性の高い理由は、あなたがtrueにLazyLoadingEnabled propertyが設定されていることです。

この場合、元のクエリではユーザーは復元されません。しかし、このプロパティにアクセスしようとすると、たとえそれをデバッグ中に検査しても、データベースからロードされます。しかし、あなたがそれにアクセスしようとする場合にのみ。

このチェックボックスをオンにすると、SQL Server Profilerが開き、DBに送信されるコマンドが表示されます。

あなたのコードは熱心な読み込みや明示的な読み込みを使用していません。だからこれが理由でなければならない。

0

JobのUserプロパティにアクセスするまで、ユーザーは実際にはコンテキストにアタッチされません。 Userに対してnullを取得する場合は、Lazy Loadingをオフにします。

関連する問題