2012-05-02 9 views
4

だから私は非常に単純な構造を有する:私はユニークな注文番号を持って受注を持って非常に悪いパフォーマンスが

  • 注文が多くOrderRows
  • OrderRowsが多くRowExtrasを持っている持っていますposition(OrderRow内のRowExtraのシーケンス番号)とInfo(文字列)の2つのフィールドがあります。多くの場合、OrderRowには複数のRowExtraがありません。

(今のところ愚かな構造は気にしないでください)

だから今、私は3つのプロパティを持つオブジェクトのリストを取得:

  • 注文番号
  • ポジション
  • 情報

私は何をしたいことは、単に1である)かどうかを確認指定されたOrderNumber/Position-pairを持つRowExtraがデータベースに存在し、その場合は2)Infoプロパティを更新します。

私はこれを達成するためにいくつかの方法を試しましたが、結果は非常に悪いです。オブジェクトのリストをソリューションループと、このような

myContext.RowExtras.Where(x => x.Position == currentPosition && 
          x.OrderRow.Order.OrderNumber == currentOrderNumber) 

または他の側から

myContext.Orders.Where(x => x.OrderNumber == currentOrderNumber) 
       .SelectMany(x => x.OrderRows) 
       .SelectMany(x => x.RowExtras) 
       .Where(x => x.Position == currentPosition) 

を行くようクエリを発行して、カウントがプロパティを更新し、1にし、そうであれば等しいかどうかを確認それ以外の場合は次の項目に進みます。

現在、データベースには約4000個のRowExtrasがあり、そのうちの約半分を更新する必要があります。これらの方法では、手順を完了するまでに数分かかるため、実際には受け入れられません。私が理解していないのは、必要なRowExtraを返すSQL節が手動で書くことが非常に簡単なので(2つの結合とwhere-partの2つの条件で)、このような長い時間がかかる理由です。

私は達成するために管理し、最高のパフォーマンスがこの

Func<MyContext, int, string, IQueryable<RowExtra>> query = 
CompiledQuery.Compile( 
    (MyContext ctx, int position, string orderNumber) => 
    from extra in ctx.RowExtras 
    where 
     extra.Position == position && 
     extra.OrderRow.Order == orderNumber 
    select extra); 

のように見えるし、その後、私のリスト内の各オブジェクトについて語ったクエリを呼び出すcompiledqueryしていました。しかし、このアプローチでも1分以上かかる。だから私は実際にこのことを合理的な時間枠内で実行するにはどうすればいいのですか?

また、長すぎる説明には申し訳ありませんが、うまくいけば誰かが私を助けることができます!

+2

クエリ自体はおそらく問題ではありません。つまり、2000個の個別の更新を行う可能性が高いということです。 – BrokenGlass

+0

データベースでより一般的な要求を行い、インメモリを処理する可能性がありますか?私の論理は、私がデータベースを使いこなすことが少なくて済むことです。 – Brendan

+0

ええ、まあそれはおそらく更新の約半分は必要ではない、つまり、新しいInfoがdbに保存されているものと同じであることを意味します。小切手を追加して、それが古いものと異なる場合にのみプロパティを更新するか、EFがその種のものを自動的に処理するかどうかが役立ちますか? – bobblez

答えて

1

データベース呼び出しの回数を最小限に抑えてください。経験則として、それぞれは少なくとも10ミリ秒かかるでしょう - スカラーを返すものでさえも。

一般に、必要なすべてのデータを一度に取り出し、コードで修正して保存します。

List<Order> orders = myContext.Orders 
    .Include("OrderRows.RowExtras") 
    .Where(... select all the orders you want, not just one at a time ...) 
    .ToList(); 

foreach (Order order in orders) 
{ 
    ... execute your logic on the in-memory model 
} 

myContext.SaveChanges();